local extension = Package("skhunlie")
extension.extensionName = "jilvRem"

local U = require "packages/utility/utility"
local SkUtil = require "packages/jilvRem/utility/sk_util"

Fk:loadTranslationTable{
  ["skhunlie"] = "极略三国-魂烈",
}

local godhuangyueying = General(extension, "sk__godhuangyueying", "god", 3, 3, General.Female)
local sk__zhiming = fk.CreateActiveSkill{
  name = "sk__zhiming",
  anim_type = "control",
  card_num = 0,
  min_target_num = 1,
  prompt = function ()
    return "#sk__zhiming:::"..Self.hp
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected < player.hp and to_select ~= player.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:sortPlayersByAction(effect.tos)
    local targets = table.map(effect.tos, Util.Id2PlayerMapper)
    local id = 1
    local current_phase = room.logic:getCurrentEvent():findParent(GameEvent.Phase, true)
    room.logic:getEventsByRule(GameEvent.Phase, 1, function (e)
      if e.data[1] == player and e.data[2] == Player.Play and current_phase and e.id ~= current_phase.id then
        id = e.id
        return true
      end
    end, 1)
    local mark = player:getTableMark(self.name)
    if #mark > 0 and mark[1] ~= id then
      mark = {}
    end
    local choices = {}
    if #mark == 0 or not table.contains(mark[2], 1) then
      if room:askForSkillInvoke(player, self.name, nil, "#sk__zhiming1-invoke") then
        table.insert(choices, 1)
        room:loseHp(player, 1, self.name)
      end
    end
    if not player.dead and (#mark == 0 or not table.contains(mark[2], 2)) then
      if room:askForSkillInvoke(player, self.name, nil, "#sk__zhiming2-invoke") then
        table.insert(choices, 2)
        player:turnOver()
      end
    end
    local n = 0
    if not player.dead and not player:isNude() and (#mark == 0 or not table.contains(mark[2], 3)) then
      local cards = room:askForDiscard(player, 1, 999, true, self.name, true, ".", "#sk__zhiming3-invoke")
      if #cards > 0 then
        table.insert(choices, 3)
        n = #cards
      end
    end
    for _, p in ipairs(targets) do
      if not p.dead and table.contains(choices, 1) then
        room:loseHp(p, 1, self.name)
      end
      if not p.dead and table.contains(choices, 2) then
        p:turnOver()
      end
      if not p.dead and not p:isNude() and table.contains(choices, 3) then
        room:askForDiscard(p, n, n, true, self.name, false)
      end
    end
    if not player.dead and player.phase == Player.Play and current_phase then
      room:setPlayerMark(player, self.name, {current_phase.id, choices})
      return
    end
    room:setPlayerMark(player, self.name, 0)
  end,
}
local sk__suyin = fk.CreateTriggerSkill{
  name = "sk__suyin",
  anim_type = "control",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:isKongcheng() then
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              return true
            end
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
      "#sk__suyin-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    to:turnOver()
    if not to.dead and to:isWounded() and to.faceup then
      room:recover({
        who = to,
        num = to:getLostHp(),
        recoverBy = player,
        skillName = self.name,
      })
    end
  end,
}
godhuangyueying:addSkill(sk__zhiming)
godhuangyueying:addSkill(sk__suyin)
Fk:loadTranslationTable{
  ["sk__godhuangyueying"] = "神黄月英",
  ["#sk__godhuangyueying"] = "华裳羽梦",

  ["sk__zhiming"] = "知命",
  [":sk__zhiming"] = "出牌阶段限一次，你可以选择至多X名其他角色（X为你的体力值），然后你依次选择是否失去1点体力、翻面、弃置任意张牌（不能执行"..
  "你上个出牌阶段执行过的效果），若如此做，这些角色依次执行你选择执行的效果。",
  ["sk__suyin"] = "夙隐",
  [":sk__suyin"] = "当你失去所有手牌后，你可以令一名角色翻面，然后若其武将牌正面朝上，你令其回复体力至体力上限。",
  ["#sk__zhiming"] = "知命：选择至多%arg名角色，与你一起执行失去体力、翻面或弃牌",
  ["#sk__zhiming1-invoke"] = "知命：是否失去1点体力？",
  ["#sk__zhiming2-invoke"] = "知命：是否翻面？",
  ["#sk__zhiming3-invoke"] = "知命：是否弃置任意张牌？",
  ["#sk__suyin-choose"] = "夙隐：你可以令一名角色翻面，然后若其正面朝上，其回复满体力",

  ["$sk__zhiming"] = "风起日落，天行有常。",
  ["$sk__suyin"] = "欲别去归隐，不复奢望。",
  ["~sk__godhuangyueying"] = "只盼明日能共沐晨光……",
}

local godzhangjiao = General(extension, "sk__godzhangjiao", "god", 3)
local sk__dianjie = fk.CreateTriggerSkill{
  name = "sk__dianjie",
  anim_type = "offensive",
  events = {fk.EventPhaseChanging},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and (data.to == Player.Draw or data.to == Player.Play)
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#sk__dianjie"..(data.to - 3).."-invoke")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local judge = {
      who = player,
      reason = self.name,
      pattern = ".|.|spade,club",
    }
    room:judge(judge)
    if player.dead then return end
    if judge.card.suit == Card.Club then
      local targets = table.map(table.filter(room.alive_players, function(p)
        return not p.chained end), Util.IdMapper)
      if #targets == 0 then return end
      local tos = room:askForChoosePlayers(player, targets, 1, 999, "#sk__dianjie1-choose", self.name, true)
      if #tos > 0 then
        room:sortPlayersByAction(tos)
        for _, id in ipairs(tos) do
          room:getPlayerById(id):setChainState(true)
        end
      end
    elseif judge.card.suit == Card.Spade then
      local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
        "#sk__dianjie2-choose", self.name, true)
      if #to > 0 then
        room:damage{
          from = player,
          to = room:getPlayerById(to[1]),
          damage = 2,
          damageType = fk.ThunderDamage,
          skillName = self.name,
        }
      end
    end
  end,
}
local sk__shendao = fk.CreateTriggerSkill{
  name = "sk__shendao",
  anim_type = "control",
  events = {fk.AskForRetrial},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and (not player:isKongcheng() or
      table.find(player.room.alive_players, function(p)
        return #p:getCardIds("ej") > 0
      end))
  end,
  on_cost = function(self, event, target, player, data)
    local success, dat = player.room:askForUseActiveSkill(player, "sk__shendao_active", "#sk__shendao-invoke::"..target.id, true)
    if success then
      self.cost_data = dat
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if #self.cost_data.cards > 0 then
      local card = Fk:getCardById(self.cost_data.cards[1])
      local resp = {
        from = player.id,
        card = card,
        skipDrop = true,
      }
      room:responseCard(resp)
      room:retrial(card, player, data, self.name, true)
    else
      local to = room:getPlayerById(self.cost_data.targets[1])
      local card = room:askForCardChosen(player, to, "ej", self.name, "#sk__shendao-retrial::"..target.id)
      local move1 = {
        ids = {card},
        from = to.id,
        toArea = Card.Processing,
        moveReason = fk.ReasonJustMove,
        skillName = self.name,
        proposer = player.id,
      }
      local move2 = {
        ids = {data.card:getEffectiveId()},
        to = player.id,
        toArea = Card.PlayerHand,
        moveReason = fk.ReasonJustMove,
        skillName = self.name,
      }
      room:moveCards(move1, move2)
      data.card = Fk:getCardById(move1.ids[1])
      room:sendLog{
        type = "#ChangedJudge",
        from = player.id,
        to = {target.id},
        card = {move1.ids[1]},
        arg = self.name,
      }
    end
  end,
}
local sk__shendao_active = fk.CreateActiveSkill{
  name = "sk__shendao_active",
  min_card_num = 0,
  max_card_num = 1,
  min_target_num = 0,
  max_target_num = 1,
  card_filter = function (self, to_select, selected)
    return #selected == 0 and Fk:currentRoom():getCardArea(to_select) == Player.Hand
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected_cards == 0 and #selected == 0 and
      #Fk:currentRoom():getPlayerById(to_select):getCardIds("ej") > 0
  end,
  feasible = function (self, selected, selected_cards)
    return #selected + #selected_cards == 1
  end,
}
local sk__leihun = fk.CreateTriggerSkill{
  name = "sk__leihun",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.damageType == fk.ThunderDamage
  end,
  on_use = function(self, event, target, player, data)
    if player:isWounded() then
      player.room:recover({
        who = player,
        num = math.min(data.damage, player:getLostHp()),
        recoverBy = player,
        skillName = self.name,
      })
    end
    return true
  end,
}
Fk:addSkill(sk__shendao_active)
godzhangjiao:addSkill(sk__dianjie)
godzhangjiao:addSkill(sk__shendao)
godzhangjiao:addSkill(sk__leihun)
Fk:loadTranslationTable{
  ["sk__godzhangjiao"] = "神张角",
  ["#sk__godzhangjiao"] = "驱雷策电",

  ["sk__dianjie"] = "电界",
  [":sk__dianjie"] = "摸牌阶段或出牌阶段开始前，你可以跳过此阶段并判定，若结果为：♣，你可以令任意名角色横置；♠，你可以对一名角色"..
  "造成2点雷电伤害。",
  ["sk__shendao"] = "神道",
  [":sk__shendao"] = "当一名角色的判定结果确定前，你可以打出一张手牌或选择场上的一张牌代替之，你获得原判定牌。",
  ["sk__leihun"] = "雷魂",
  [":sk__leihun"] = "锁定技，当你受到雷电伤害时，防止此伤害，改为回复等量的体力。",
  ["#sk__dianjie1-invoke"] = "电界：是否跳过摸牌阶段并判定？",
  ["#sk__dianjie2-invoke"] = "电界：是否跳过出牌阶段并判定？",
  ["#sk__dianjie1-choose"] = "电界：你可以令任意名角色横置",
  ["#sk__dianjie2-choose"] = "电界：你可以对一名角色造成2点雷电伤害！",
  ["#sk__shendao-invoke"] = "神道：打出一张手牌或选择一名角色场上的一张牌修改 %dest 的判定，你获得原判定牌",
  ["sk__shendao_active"] = "神道",
  ["#sk__shendao-retrial"] = "神道：选择一张牌代替 %dest 的判定牌",

  ["$sk__dianjie1"] = "电破苍穹，雷震九州！",
  ["$sk__dianjie2"] = "风雷如律令，法咒显圣灵！",
  ["$sk__shendao"] = "人世之伎俩，于鬼神无用！",
  ["$sk__leihun"] = "肉体凡胎，也敢扰我清净！",
  ["~sk__godzhangjiao"] = "吾之信仰，也将化为微尘……",
}

local godlvmeng = General(extension, "sk__godlvmeng", "god", 3)
local sk__shelie = fk.CreateTriggerSkill{
  name = "sk__shelie",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and not table.contains(player:getTableMark("sk__shelie-turn"), data.card.type)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark("sk__shelie-turn")
    table.insert(mark, data.card.type)
    room:setPlayerMark(player, "sk__shelie-turn", mark)
    local cards = room:getCardsFromPileByRule(".|.|.|.|.|^"..data.card:getTypeString(), 2, "drawPile")
    if #cards > 0 then
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, false, player.id)
    end
  end,
}
local sk__gongxin = fk.CreateActiveSkill{
  name = "sk__gongxin",
  anim_type = "control",
  prompt = "#sk__gongxin",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and to_select ~= player.id and not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local suits = {"log_spade", "log_heart", "log_club", "log_diamond"}
    local ids, _ = U.askforChooseCardsAndChoice(player, target:getCardIds("h"), {"OK"},
      self.name, "#sk__gongxin-prey::"..target.id, {}, 1, 1, target:getCardIds("h"))
    local suit1 = Fk:getCardById(ids[1]):getSuitString(true)
    table.removeOne(suits, suit1)
    room:moveCardTo(ids, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
    if target.dead then return end
    if not player.dead and not target:isKongcheng() then
      local cards2 = table.filter(target:getCardIds("h"), function (id)
        return Fk:getCardById(id):getSuitString(true) ~= suit1
      end)
      local n = #cards2 > 0 and 1 or 0
      ids, _ = U.askforChooseCardsAndChoice(player, cards2, {"OK"},
        self.name, "#sk__gongxin-discard::"..target.id, {}, n, 1, target:getCardIds("h"))
      if #ids > 0 then
        table.removeOne(suits, Fk:getCardById(ids[1]):getSuitString(true))
        room:throwCard(ids, self.name, target, player)
      end
    end
    if target.dead then return end
    room:setPlayerMark(target, "@sk__gongxin-turn", suits)
  end,
}
local sk__gongxin_prohibit = fk.CreateProhibitSkill{
  name = "#sk__gongxin_prohibit",
  prohibit_use = function(self, player, card)
    if player:getMark("@sk__gongxin-turn") ~= 0 and card and
      table.contains(player:getMark("@sk__gongxin-turn"), card:getSuitString(true)) then
      local subcards = card:isVirtual() and card.subcards or {card.id}
      return #subcards > 0 and table.every(subcards, function(id)
        return table.contains(player:getCardIds("h"), id)
      end)
    end
  end,
  prohibit_response = function(self, player, card)
    if player:getMark("@sk__gongxin-turn") ~= 0 and card and
      table.contains(player:getMark("@sk__gongxin-turn"), card:getSuitString(true)) then
      local subcards = card:isVirtual() and card.subcards or {card.id}
      return #subcards > 0 and table.every(subcards, function(id)
        return table.contains(player:getCardIds("h"), id)
      end)
    end
  end,
}
sk__gongxin:addRelatedSkill(sk__gongxin_prohibit)
godlvmeng:addSkill(sk__shelie)
godlvmeng:addSkill(sk__gongxin)
Fk:loadTranslationTable{
  ["sk__godlvmeng"] = "神吕蒙",
  ["#sk__godlvmeng"] = "圣光国士",

  ["sk__shelie"] = "涉猎",
  [":sk__shelie"] = "锁定技，当你使用牌后（每回合每种类别限一次），你从牌堆随机获得两张与此牌类别不同的牌。",
  ["sk__gongxin"] = "攻心",
  [":sk__gongxin"] = "出牌阶段限一次，你可以观看一名其他角色的手牌，你先获得其中一张牌，再弃置其中一张另一种花色的牌，然后该角色于本回合内"..
  "不能使用或打出除这些牌以外花色的手牌。",
  ["#sk__gongxin"] = "攻心：观看一名角色的手牌，获得其中一张，再弃置其中不同花色的一张",
  ["#sk__gongxin-prey"] = "攻心：获得 %dest 的一张手牌",
  ["#sk__gongxin-discard"] = "攻心：弃置 %dest 的一张手牌",
  ["@sk__gongxin-turn"] = "攻心",

  ["$sk__shelie"] = "涉猎阅旧闻，暂使心魂澄。",
  ["$sk__gongxin"] = "攻城为下，攻心为上。",
  ["~sk__godlvmeng"] = "死去方知万事空。",
}

local godzhangliao = General(extension, "sk__godzhangliao", "god", 4)
local sk__nizhan = fk.CreateTriggerSkill{
  name = "sk__nizhan",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Start and not target.dead and
      (target:isWounded() or target:getMark("@sk__nizhan") > 0)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if target:isWounded() then
      room:addPlayerMark(target, "@sk__nizhan", 1)
    else
      room:removePlayerMark(target, "@sk__nizhan", 1)
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player and not table.find(player.room:getOtherPlayers(player), function(p)
      return p:hasSkill(self, true, true)
    end) then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAlivePlayers()) do
      room:setPlayerMark(p, "@sk__nizhan", 0)
    end
  end,
}
local sk__cuifeng = fk.CreateActiveSkill{
  name = "sk__cuifeng",
  anim_type = "offensive",
  card_num = 0,
  target_num = 2,
  prompt  =function (self, selected_cards, selected_targets)
    if #selected_targets == 0 then
      return "#sk__cuifeng0"
    elseif #selected_targets == 1 then
      return "#sk__cuifeng1:"..selected_targets[1]
    elseif #selected_targets == 2 then
      return "#sk__cuifeng2:"..selected_targets[1]..":"..selected_targets[2]
    end
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected == 0 then
      return Fk:currentRoom():getPlayerById(to_select):getMark("@sk__nizhan") > 0
    else
      return #selected == 1
    end
  end,
  on_use = function(self, room, effect)
    local target1 = room:getPlayerById(effect.tos[1])
    local target2 = room:getPlayerById(effect.tos[2])
    room:removePlayerMark(target1, "@sk__nizhan", 1)
    room:addPlayerMark(target2, "@sk__nizhan", 1)
    room:useVirtualCard("slash", nil, target1, target2, self.name, true)
  end,
}
local sk__weizhen = fk.CreateTriggerSkill{
  name = "sk__weizhen",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.DrawNCards, fk.DamageCaused},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.DrawNCards then
        return (target:getMark("@sk__nizhan") > 1 and data.n > 0) or
          (target == player and table.find(player.room.alive_players, function (p)
            return p:getMark("@sk__nizhan") > 0
          end))
      elseif event == fk.DamageCaused then
        return target and target == player and data.to:getMark("@sk__nizhan") > 2
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    if event == fk.DrawNCards then
      if target:getMark("@sk__nizhan") > 1 then
        if target ~= player then
          room:doIndicate(player.id, {target.id})
          room:notifySkillInvoked(player, self.name, "control")
        end
        data.n = data.n - 1
      end
      if target == player then
        room:notifySkillInvoked(player, self.name, "drawcard")
        data.n = data.n + #table.filter(room.alive_players, function (p)
          return p:getMark("@sk__nizhan") > 0
        end)
      end
    elseif event == fk.DamageCaused then
      room:doIndicate(player.id, {data.to.id})
      room:notifySkillInvoked(player, self.name, "offensive")
      data.damage = data.damage + 1
    end
  end,
}
local sk__weizhen_invalidity = fk.CreateInvaliditySkill {
  name = "#sk__weizhen_invalidity",
  frequency = Skill.Compulsory,
  main_skill = sk__weizhen,
  invalidity_func = function(self, from, skill)
    if from:getMark("@sk__nizhan") > 3 and skill.frequency ~= Skill.Compulsory and skill.frequency ~= Skill.Wake and
      skill:isPlayerSkill(from) then
      for _, p in ipairs(Fk:currentRoom().alive_players) do
        if p:hasSkill(sk__weizhen) then
          return true
        end
      end
    end
  end,
}
sk__weizhen:addRelatedSkill(sk__weizhen_invalidity)
godzhangliao:addSkill(sk__nizhan)
godzhangliao:addSkill(sk__cuifeng)
godzhangliao:addSkill(sk__weizhen)
Fk:loadTranslationTable{
  ["sk__godzhangliao"] = "神张辽",
  ["#sk__godzhangliao"] = "风驰电掣",

  ["sk__nizhan"] = "逆战",
  [":sk__nizhan"] = "锁定技，一名角色准备阶段，若其已受伤，其获得1枚“逆战”标记；若其未受伤，其弃置1枚“逆战”标记。",
  ["sk__cuifeng"] = "摧锋",
  [":sk__cuifeng"] = "出牌阶段限一次，你可以移动场上的1枚“逆战”标记，视为移动前的角色对移动后的角色使用一张【杀】。",
  ["sk__weizhen"] = "威震",
  [":sk__weizhen"] = "锁定技，若一名角色的“逆战”标记数不少于：1，你摸牌阶段摸牌数+1；<br>2，其摸牌阶段摸牌数-1；<br>"..
  "3，你对其造成的伤害+1；<br>4，其非锁定技无效。",
  ["@sk__nizhan"] = "逆战",
  ["#sk__cuifeng"] = "摧锋：移动一枚“逆战”标记，视为移动前的角色对移动后的角色使用一张【杀】",
  ["#sk__cuifeng0"] = "摧锋：选择一名角色移动其“逆战”标记",
  ["#sk__cuifeng1"] = "摧锋：选择第二名角色获得“逆战”标记，视为 %src 对其使用【杀】",
  ["#sk__cuifeng2"] = "摧锋：将 %src 一枚“逆战”标记移动给 %dest，视为 %src 对 %dest 使用【杀】",

  ["$sk__nizhan"] = "已是成败二分之时！",
  ["$sk__cuifeng"] = "全军化为一体，总攻！",
  ["$sk__weizhen"] = "让你见识我军的真正实力！",
  ["~sk__godzhangliao"] = "不求留名青史，但求无愧于心……",
}

local godluxun = General(extension, "sk__godluxun", "god", 3)
local sk__jieyan = fk.CreateTriggerSkill{
  name = "sk__jieyan",
  anim_type = "offensive",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and (data.card.trueName == "slash" or data.card.type == Card.TypeTrick) and
      data.card.color == Card.Red and #AimGroup:getAllTargets(data.tos) == 1 and not player:isKongcheng() and
      not player.room:getPlayerById(data.to).dead
  end,
  on_cost = function (self, event, target, player, data)
    local card = player.room:askForDiscard(player, 1, 1, false, self.name, true, ".",
      "#sk__jieyan-invoke::"..data.to..":"..data.card:toLogString(), true)
    if #card > 0 then
      self.cost_data = card
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {data.to})
    room:throwCard(self.cost_data, self.name, player, player)
    table.insertIfNeed(data.nullifiedTargets, data.to)
    local to = room:getPlayerById(data.to)
    if not to.dead then
      room:damage{
        from = player,
        to = to,
        damage = 1,
        damageType = fk.FireDamage,
        skillName = self.name,
      }
    end
  end,
}
local sk__fenying = fk.CreateTriggerSkill{
  name = "sk__fenying",
  anim_type = "drawcard",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.damageType == fk.FireDamage
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:drawCards(1, self.name)
    if player.dead or target.dead or player:isNude() then return end
    local targets = table.map(table.filter(room:getOtherPlayers(target), function(p2)
      return table.every(room:getOtherPlayers(target), function(p1)
        return target:distanceTo(p1) >= target:distanceTo(p2)
      end)
    end), Util.IdMapper)
    table.insert(targets, target.id)
    local n = player:usedSkillTimes(self.name, Player.HistoryTurn)
    room:setPlayerMark(player, "sk__fenying-tmp", {n, targets})
    local success, dat = room:askForUseActiveSkill(player, "sk__fenying_active",
      "#sk__fenying-invoke::"..target.id..":"..n..":"..data.damage, true, nil, false)
    room:setPlayerMark(player, "sk__fenying-tmp", 0)
    if success then
      local to = room:getPlayerById(dat.targets[1])
      room:throwCard(dat.cards, self.name, player, player)
      if not to.dead then
        room:damage{
          from = player,
          to = to,
          damage = data.damage,
          damageType = fk.FireDamage,
          skillName = self.name,
        }
      end
    end
  end,
}
local sk__fenying_active = fk.CreateActiveSkill{
  name = "sk__fenying_active",
  card_num =function ()
    return Self:getMark("sk__fenying-tmp")[1]
  end,
  target_num = 1,
  card_filter =function (self, to_select, selected, player)
    return #selected < player:getMark("sk__fenying-tmp")[1] and not player:prohibitDiscard(to_select)
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and table.contains(player:getMark("sk__fenying-tmp")[2], to_select)
  end,
}
Fk:addSkill(sk__fenying_active)
godluxun:addSkill(sk__jieyan)
godluxun:addSkill(sk__fenying)
Fk:loadTranslationTable{
  ["sk__godluxun"] = "神陆逊",
  ["#sk__godluxun"] = "燎原之火",

  ["sk__jieyan"] = "劫焰",
  [":sk__jieyan"] = "当一名角色使用红色【杀】或红色普通锦囊牌指定唯一目标后，你可以弃置一张手牌令此牌无效，然后你对目标角色造成1点火焰伤害。",
  ["sk__fenying"] = "焚营",
  [":sk__fenying"] = "当一名角色受到火焰伤害后，你可以摸一张牌，然后你可以弃置X张牌（X为本回合发动此技能的次数），对其或其距离最近的"..
  "一名角色造成等量的火焰伤害。",
  ["#sk__jieyan-invoke"]= "劫焰：你可以弃置一张手牌，令此%arg对 %dest 无效，并对其造成1点火焰伤害",
  ["sk__fenying_active"] = "焚营",
  ["#sk__fenying-invoke"] = "焚营：你可以弃置%arg张牌，对 %dest 或其距离最近的角色造成%arg2点火焰伤害",

  ["$sk__jieyan"] = "炙灼之气，已溢满万界！",
  ["$sk__fenying"] = "随着大火，往生去吧！",
  ["~sk__godluxun"] = "火，终究是无情之物……",
}

local godguojia = General(extension, "sk__godguojia", "god", 3)
local sk__tianqi = fk.CreateViewAsSkill{
  name = "sk__tianqi",
  pattern = ".|.|.|.|.|basic,trick",
  prompt = "#sk__tianqi",
  interactio=function (self,player)
    local all_names = U.getAllCardNames("bt")
    local names = U.getViewAsCardNames(player, "sk__tianqi", all_names)
    return U.CardNameBox { choices = names, all_choices = all_names }
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if not self.interaction or not self.interaction.data then return end
    local card = Fk:cloneCard(self.interaction.data)
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player, use)
    local room = player.room
    if Fk.currentResponsePattern == nil and player.phase == Player.Play then
      room:setPlayerMark(player, "sk__tianqi-phase", 1)
    end
    if room.draw_pile == 0 then
      room:shuffleDrawPile()
      if room.draw_pile == 0 then
        room:gameOver("")
      end
    end
    local id = room.draw_pile[1]
    use.card:addSubcard(id)
    if Fk:getCardById(id).type ~= use.card.type and not player.dead then
      room:loseHp(player, 1, self.name)
    end
  end,
  enabled_at_play = function(self, player)
    return player:getMark("sk__tianqi-phase") == 0 and self.interaction and self.interaction.data
  end,
  enabled_at_response = function(self, player, response)
    return not player.dying and Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):matchExp(self.pattern)
      and self.interaction and self.interaction.data
  end,
}
local sk__tianji = fk.CreateTriggerSkill{
  name = "sk__tianji",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Play
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if room.draw_pile == 0 then
      room:shuffleDrawPile()
      if room.draw_pile == 0 then
        room:gameOver("")
      end
    end
    if player.dead then return end
    if table.every(room.alive_players, function (p)
      return player:getHandcardNum() >= p:getHandcardNum()
    end) then
      local result = U.askForExchange(player, "Top", player.general, {room.draw_pile[1]}, player:getCardIds("h"),
        "#sk__tianji-swap", 1, true)
      if #result == 2 then
        local card = result[1]
        if table.contains(player:getCardIds("h"), result[2]) then
          card = result[2]
        end
        U.swapCardsWithPile(player, {card}, {room.draw_pile[1]}, self.name, "Top", false, player.id)
      end
    else
      local choice = U.askforViewCardsAndChoice(player, {room.draw_pile[1]}, {"OK", "Cancel"}, self.name, "#sk__tianji-choice")
      if choice == "OK" then
        room:moveCardTo(room.draw_pile[1], Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, false, player.id)
      end
    end
  end,
}
godguojia:addSkill(sk__tianqi)
godguojia:addSkill(sk__tianji)
Fk:loadTranslationTable{
  ["sk__godguojia"] = "神郭嘉",
  ["#sk__godguojia"] = "驭魂画策",

  ["sk__tianqi"] = "天启",
  [":sk__tianqi"] = "出牌阶段限一次，或当你不处于濒死状态时，你可以将牌堆顶牌当任意基本牌或普通锦囊牌使用或打出。若用于转化的牌和转化后的牌"..
  "类别不同，你使用前先失去1点体力。",
  ["sk__tianji"] = "天机",
  [":sk__tianji"] = "一名角色出牌阶段开始时，你可以观看牌堆顶牌，然后若你的手牌数：全场最多，你可以用一张手牌替换之；不为最多，你可以获得之。",
  ["#sk__tianqi"] = "天启：你可以将牌堆顶牌当任意基本牌或普通锦囊牌使用或打出",
  ["#sk__tianji-swap"] = "天机：是否用手牌交换牌堆顶牌？",
  ["#sk__tianji-choice"] = "天机：是否获得牌堆顶牌？",

  ["$sk__tianqi1"] = "荡破天光，领得天启！",
  ["$sk__tianqi2"] = "谋事在人，成事在天。",
  ["$sk__tianji"] = "天机可知却不可说。",
  ["~sk__godguojia"] = "窥天意，竭心力，皆为吾主。",
}

local godguanyu = General(extension, "sk__godguanyu", "god", 5)
local sk__wushen = fk.CreateTriggerSkill{
  name = "sk__wushen",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    return target and target == player and player:hasSkill(self) and data.to ~= player and
      not table.contains({"wei", "shu", "wu", "qun"}, Fk.generals[data.to.general].kingdom)
  end,
  on_use = function(self, event, target, player, data)
    data.damage = data.damage + 1
  end,
}
local sk__wushen_filter = fk.CreateFilterSkill{
  name = "#sk__wushen_filter",
  mute = true,
  frequency = Skill.Compulsory,
  main_skill = sk__wushen,
  card_filter = function(self, card, player, isJudgeEvent)
    return player:hasSkill(sk__wushen) and (card.trueName == "slash" or card.trueName == "peach")
  end,
  view_as = function(self, to_select)
    return Fk:cloneCard("duel", to_select.suit, to_select.number)
  end,
}
local sk__suohun = fk.CreateTriggerSkill{
  name = "sk__suohun",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.Damage, fk.Damaged, fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    if target and target == player and player:hasSkill(self) then
      if event == fk.EnterDying then
        return true
      else
        return data.from ~= data.to and not (data.from.dead or data.to.dead)
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.Damage then
      room:addPlayerMark(data.to, "@sk__suohun", 1)
    elseif event == fk.Damaged then
      room:addPlayerMark(data.from, "@sk__suohun", data.damage)
    elseif event == fk.EnterDying then
      room:changeMaxHp(player, -((player.maxHp + 1) // 2))
      if not player.dead and player:isWounded() then
        room:recover({
          who = player,
          num = player:getLostHp(),
          recoverBy = player,
          skillName = self.name,
        })
      end
      local targets = table.filter(room.alive_players, function (p)
        return p:getMark("@sk__suohun") > 0
      end)
      if #targets == 0 then return end
      room:doIndicate(player.id, table.map(targets, Util.IdMapper))
      for _, p in ipairs(targets) do
        if not p.dead then
          local n = p:getMark("@sk__suohun")
          room:setPlayerMark(p, "@sk__suohun", 0)
          room:damage{
            from = player,
            to = p,
            damage = n,
            skillName = self.name,
          }
        end
      end
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player and not table.find(player.room:getOtherPlayers(player), function(p)
      return p:hasSkill(self, true, true)
    end) then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAlivePlayers()) do
      room:setPlayerMark(p, "@sk__suohun", 0)
    end
  end,
}
sk__wushen:addRelatedSkill(sk__wushen_filter)
godguanyu:addSkill(sk__wushen)
godguanyu:addSkill(sk__suohun)
Fk:loadTranslationTable{
  ["sk__godguanyu"] = "神关羽",
  ["#sk__godguanyu"] = "炼狱武神",

  ["sk__wushen"] = "武神",
  [":sk__wushen"] = "锁定技，你的【杀】和【桃】视为【决斗】；你对武将牌势力不为魏、蜀、吴、群的其他角色造成伤害+1。",
  ["sk__suohun"] = "索魂",
  [":sk__suohun"] = "锁定技，当你对其他角色造成伤害后，你令其获得1枚“索魂”标记；当你受到其他角色造成的1点伤害后，你令其获得等量的"..
  "“索魂”标记。<br>当你进入濒死状态时，你减一半（向上取整）的体力上限，回复体力至体力上限，然后拥有“索魂”标记的角色弃置所有的“索魂”标记，"..
  "你对其造成其弃置“索魂”标记数的伤害。",
  ["#sk__wushen_filter"] = "武神",
  ["@sk__suohun"] = "索魂",

  ["$sk__wushen"] = "武神现世，天下莫敌！",
  ["$sk__suohun"] = "还不速速领死！",
  ["~sk__godguanyu"] = "吾一世英名，竟葬于小人之手！",
}

local godsimayi = General(extension, "sk__godsimayi", "god", 3)
local sk__jilve = fk.CreateTriggerSkill{
  name = "sk__jilve",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function (self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}
local sk__tongtian = fk.CreateActiveSkill{
  name = "sk__tongtian",
  anim_type = "special",
  frequency = Skill.Limited,
  card_num = 0,
  target_num = 0,
  prompt = "#sk__tongtian",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    player:drawCards(4, self.name)
    if player.dead or player:isNude() then return end
    local success, dat = room:askForUseActiveSkill(player, "sk__tongtian_active", "#sk__tongtian-discard", true)
    if success and dat then
      local skills = {}
      for _, id in ipairs(dat.cards) do
        if Fk:getCardById(id).suit == Card.Spade then
          table.insert(skills, "ex__fankui")
        elseif Fk:getCardById(id).suit == Card.Heart then
          table.insert(skills, "ex__guanxing")
        elseif Fk:getCardById(id).suit == Card.Club then
          table.insert(skills, "wansha")
        elseif Fk:getCardById(id).suit == Card.Diamond then
          table.insert(skills, "ex__zhiheng")
        end
      end
      room:throwCard(dat.cards, self.name, player, player)
      if not player.dead then
        room:handleAddLoseSkills(player, skills, nil, true, false)
      end
    end
  end
}
local sk__tongtian_active = fk.CreateActiveSkill{
  name = "sk__tongtian_active",
  min_card_num = 1,
  max_card_num = 4,
  target_num = 0,
  card_filter =function (self, to_select, selected, player)
    if not player:prohibitDiscard(to_select) then
      return table.every(selected, function (id)
        return Fk:getCardById(to_select).suit ~= Fk:getCardById(id).suit
      end)
    end
  end,
}
Fk:addSkill(sk__tongtian_active)
godsimayi:addSkill(sk__jilve)
godsimayi:addSkill(sk__tongtian)
godsimayi:addRelatedSkill("ex__fankui")
godsimayi:addRelatedSkill("ex__guanxing")
godsimayi:addRelatedSkill("wansha")
godsimayi:addRelatedSkill("ex__zhiheng")
Fk:loadTranslationTable{
  ["sk__godsimayi"] = "神司马懿",
  ["#sk__godsimayi"] = "鉴往知来",

  ["sk__jilve"] = "极略",
  [":sk__jilve"] = "锁定技，当你使用牌后，你摸一张牌。",
  ["sk__tongtian"] = "通天",
  [":sk__tongtian"] = "限定技，出牌阶段，你可以摸四张牌，然后弃置任意张花色各不相同的牌，根据你弃置牌的花色获得技能：<br>♠-〖反馈〗；"..
  "<font color='red'>♥</font>-〖观星〗；<br>♣-〖完杀〗；<font color='red'>♦</font>-〖制衡〗。",
  ["#sk__jilve"] = "极略：摸一张牌，然后使用一张牌或弃一张牌且“极略”本阶段失效",
  ["@@sk__jilve-phase"] = "极略失效",
  ["#sk__jilve-use"] = "极略：请使用一张手牌",
  ["#sk__tongtian"] = "通天：摸四张牌，然后弃置花色各不相同的牌，根据花色获得技能",
  ["sk__tongtian_active"] = "通天",
  ["#sk__tongtian-discard"] = "通天：弃置花色各不相同的牌，根据花色获得技能：<br>♠-〖反馈〗，<font color='red'>♥</font>-〖观星〗，"..
  "♣-〖完杀〗，<font color='red'>♦</font>-〖制衡〗",

  ["$sk__jilve1"] = "轻举妄为，徒招横祸。",
  ["$sk__jilve2"] = "因果有律，世间无常。",
  ["$sk__jilve3"] = "万物无异，强弱有别。",
  ["$sk__tongtian"] = "反乱不除，必生枝节。",
  ["$ex__fankui_sk__godsimayi"] = "逆势而为，不自量力。",
  ["$ex__guanxing_sk__godsimayi"] = "吾以身前，万籁俱寂。",
  ["$wansha_sk__godsimayi"] = "狂战似魔，深谋如鬼。",
  ["$ex__zhiheng_sk__godsimayi"] = "吾以身后，了无生机。",
  ["~sk__godsimayi"] = "生门已闭，唯有赴死。",
}

local godcaocao = General(extension, "sk__godcaocao", "god", 3)
local sk__guixin = fk.CreateTriggerSkill{
  name = "sk__guixin",
  anim_type = "masochism",
  events = {fk.Damaged},
  on_trigger = function(self, event, target, player, data)
    self.cancel_cost = false
    for _ = 1, data.damage do
      if self.cancel_cost or not player:hasSkill(self) or
      table.every(player.room:getOtherPlayers(player), function (p) return p:isAllNude() end) then break end
      self:doCost(event, target, player, data)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if room:askForSkillInvoke(player, self.name, data) then
      room:doIndicate(player.id, table.map(room.alive_players, Util.IdMapper))
      return true
    end
    self.cancel_cost = true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 0
    while table.find(room:getOtherPlayers(player), function (p) return not p:isAllNude() end) and n < 4 do
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if player.dead then return end
        if not p.dead and not p:isAllNude() then
          n = n + 1
          room:moveCardTo(table.random(p:getCardIds("hej")), Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
        end
      end
    end
    if not player.dead then
      player:turnOver()
    end
  end,
}
local sk__feiying = fk.CreateFilterSkill{
  name = "sk__feiying",
  frequency = Skill.Compulsory,
  anim_type = "support",
  card_filter = function(self, to_select,player)
    return player:hasSkill(self) and player:isWounded() and table.contains(player:getCardIds("h"), to_select.id) and
      to_select.color == Card.Red and to_select.type == Card.TypeEquip
  end,
  view_as = function(self, to_select)
    local card = Fk:cloneCard("peach", to_select.suit, to_select.number)
    card.skillName = self.name
    return card
  end,
}
local sk__feiying_targetmod = fk.CreateTargetModSkill{
  name = "#sk__feiying_targetmod",
  frequency = Skill.Compulsory,
  main_skill = sk__feiying,
  bypass_times = function(self, player, skill, scope, card)
    return player:hasSkill(sk__feiying) and not player:isWounded() and card and card.trueName == "slash" and
      card.color == Card.Black and scope == Player.HistoryPhase
  end,
  bypass_distances = function(self, player, skill, card)
    return player:hasSkill(sk__feiying) and not player:isWounded() and card and card.trueName == "slash" and
      card.color == Card.Black
  end,
}
sk__feiying:addRelatedSkill(sk__feiying_targetmod)
godcaocao:addSkill(sk__guixin)
godcaocao:addSkill(sk__feiying)
Fk:loadTranslationTable{
  ["sk__godcaocao"] = "神曹操",
  ["#sk__godcaocao"] = "王权霸业",

  ["sk__guixin"] = "归心",
  [":sk__guixin"] = "当你受到1点伤害后，你可以随机获得每名其他角色区域里的一张牌，若你以此法获得的总牌数少于4，重复此流程。然后你翻面。",
  ["sk__feiying"] = "飞影",
  [":sk__feiying"] = "锁定技，若你未受伤，你使用黑色【杀】无距离和次数限制；若你已受伤，你手牌中的红色装备牌视为【桃】。",

  ["$sk__guixin"] = "周公吐哺，天下归心！",
  ["~sk__godcaocao"] = "螣蛇乘雾，终为土灰……",
}

local godzhugeliang = General(extension, "sk__godzhugeliang", "god", 3)
local sk__qixing = fk.CreateTriggerSkill{
  name = "sk__qixing",
  events = {fk.GameStart, fk.EventPhaseEnd},
  anim_type = "drawcard",
  derived_piles = "sk__godzhugeliang_star",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif event == fk.EventPhaseEnd then
        return target == player and player.phase == Player.Draw and not player:isKongcheng() and
          #player:getPile("sk__godzhugeliang_star") > 0
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.GameStart then
      return true
    else
      return player.room:askForSkillInvoke(player, self.name, data)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      player:drawCards(7, self.name)
      if player.dead or player:isKongcheng() then return end
      local cards = room:askForCard(player, math.min(player:getHandcardNum(), 7), 999, false, self.name, false, ".",
        "#sk__qixing-put")
      player:addToPile("sk__godzhugeliang_star", cards, false, self.name, player.id)
    else
      local cards = room:askForArrangeCards(player, self.name, {player:getPile("sk__godzhugeliang_star"), player:getCardIds("h"),
        "sk__godzhugeliang_star", "$Hand"}, "#sk__qixing-exchange", true)
      U.swapCardsWithPile(player, cards[1], cards[2], self.name, "sk__godzhugeliang_star")
    end
  end,
}
local sk__qixing_maxcards = fk.CreateMaxCardsSkill{
  name = "#sk__qixing_maxcards",
  main_skill = sk__qixing,
  correct_func = function(self, player)
    if player:hasSkill(sk__qixing) then
      return #player:getPile("sk__godzhugeliang_star")
    else
      return 0
    end
  end,
}
local sk__kuangfeng = fk.CreateTriggerSkill{
  name = "sk__kuangfeng",
  events = {fk.EventPhaseStart, fk.DamageInflicted},
  anim_type = "offensive",
  expand_pile = "sk__godzhugeliang_star",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player.phase == Player.Start and #player:getPile("sk__godzhugeliang_star") > 0
      else
        return target:getMark("@sk__kuangfeng") > 0
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local success, dat = player.room:askForUseActiveSkill(player, "sk__kuangfeng_active", "#sk__kuangfeng-choose", true, nil, false)
      if success then
        self.cost_data = dat
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      room:moveCardTo(self.cost_data.cards, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, self.name, nil, true, player.id)
      local to = room:getPlayerById(self.cost_data.targets[1])
      if not to.dead then
        room:addPlayerMark(to, "@sk__kuangfeng", 1)
      end
    else
      if data.damageType == fk.NormalDamage then
        player:drawCards(target:getMark("@sk__kuangfeng"), self.name)
      elseif data.damageType == fk.FireDamage then
        data.damage = data.damage + target:getMark("@sk__kuangfeng")
      elseif data.damageType == fk.ThunderDamage then
        player:addToPile("sk__godzhugeliang_star", room:getNCards(1), false, self.name, player.id)
      end
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player and not table.find(player.room:getOtherPlayers(player), function(p)
      return p:hasSkill(self, true, true)
    end) then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAlivePlayers()) do
      room:setPlayerMark(p, "@sk__kuangfeng", 0)
    end
  end,
}
local sk__kuangfeng_active = fk.CreateActiveSkill{
  name = "sk__kuangfeng_active",
  card_num = 1,
  target_num = 1,
  expand_pile = "sk__godzhugeliang_star",
  card_filter =function (self, to_select, selected, player)
    return #selected == 0 and player:getPileNameOfId(to_select) == "sk__godzhugeliang_star"
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0
  end,
}
local sk__dawu = fk.CreateTriggerSkill{
  name = "sk__dawu",
  anim_type = "defensive",
  events = {fk.EventPhaseStart, fk.DamageInflicted},
  expand_pile = "sk__godzhugeliang_star",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player.phase == Player.Finish and #player:getPile("sk__godzhugeliang_star") > 0
      else
        return target:getMark("@@sk__dawu") > 0 and data.damageType ~= fk.ThunderDamage and
          table.contains(player:getTableMark(self.name), target.id)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local success, dat = player.room:askForUseActiveSkill(player, "sk__dawu_active", "#sk__dawu-choose", true, nil, false)
      if success then
        self.cost_data = dat
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local room = player.room
      room:setPlayerMark(player, self.name, self.cost_data.targets)
      room:moveCardTo(self.cost_data.cards, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, self.name, nil, true, player.id)
      for _, id in ipairs(self.cost_data.targets) do
        local p = room:getPlayerById(id)
        if not p.dead then
          room:addPlayerMark(p, "@@sk__dawu", 1)
        end
      end
    else
      target:drawCards(1, self.name)
      return true
    end
  end,

  refresh_events = {fk.TurnStart, fk.EventLoseSkill, fk.Death},
  can_refresh = function(self, event, target, player, data)
    if target == player and player:getMark(self.name) ~= 0 then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return true
      end
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    for _, id in ipairs(player:getMark(self.name)) do
      room:setPlayerMark(room:getPlayerById(id), "@@sk__dawu", 0)
    end
    room:setPlayerMark(player, self.name, 0)
  end,
}
local sk__dawu_active = fk.CreateActiveSkill{
  name = "sk__dawu_active",
  min_card_num = 1,
  min_target_num = 1,
  expand_pile = "sk__godzhugeliang_star",
  card_filter =function (self, to_select, selected, player)
    return #selected < #Fk:currentRoom().alive_players and player:getPileNameOfId(to_select) == "sk__godzhugeliang_star"
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected < #selected_cards
  end,
  feasible = function (self, selected, selected_cards)
    return #selected > 0 and #selected == #selected_cards
  end,
}
sk__qixing:addRelatedSkill(sk__qixing_maxcards)
Fk:addSkill(sk__kuangfeng_active)
Fk:addSkill(sk__dawu_active)
godzhugeliang:addSkill(sk__qixing)
godzhugeliang:addSkill(sk__kuangfeng)
godzhugeliang:addSkill(sk__dawu)
Fk:loadTranslationTable{
  ["sk__godzhugeliang"] = "神诸葛亮",
  ["#sk__godzhugeliang"] = "七星诛邪",

  ["sk__qixing"] = "七星",
  [":sk__qixing"] = "游戏开始时，你摸七张牌，然后将至少七张手牌置于你的武将牌上，称为“星”。摸牌阶段结束时，你可以用任意张手牌替换等量的“星”。"..
  "你的手牌上限+X（X为“星”数）。",
  ["sk__kuangfeng"] = "狂风",
  [":sk__kuangfeng"] = "准备阶段，你可以将一张“星”置入弃牌堆并选择一名角色，令其获得1枚“狂风”标记。拥有“狂风”标记的角色受到伤害时，根据此"..
  "伤害的属性：<br>普通伤害，你摸X张牌；<br>火焰伤害，此伤害+X；<br>雷电伤害，你将牌堆顶牌置为“星”。<br>（X为其“狂风”标记数)",
  ["sk__dawu"] = "大雾",
  [":sk__dawu"] = "结束阶段，你可以将至少一张“星”置入弃牌堆并选择等量的角色，令这些角色各获得1枚“大雾”标记直到你下回合开始。拥有“大雾”标记的"..
  "角色受到非雷电伤害时，防止此伤害并令其摸一张牌。",
  ["sk__godzhugeliang_star"] = "星",
  ["#sk__qixing-put"] = "七星：请将至少七张手牌置为“星”",
  ["#sk__qixing-exchange"] = "七星：你可以用任意张手牌替换等量的“星”",
  ["sk__kuangfeng_active"] = "狂风",
  ["#sk__kuangfeng-choose"] = "狂风：弃置一张“星”，令一名角色获得“狂风”标记",
  ["@sk__kuangfeng"] = "狂风",
  ["sk__dawu_active"] = "大雾",
  ["#sk__dawu-choose"] = "大雾：弃置任意张“星”，令等量角色获得“大雾”标记",
  ["@@sk__dawu"] = "大雾",

  ["$sk__qixing"] = "伏望天慈，佑我蜀汉。",
  ["$sk__kuangfeng1"] = "欲破曹公，宜用火攻。",
  ["$sk__kuangfeng2"] = "万事俱备，只欠东风。",
  ["$sk__dawu"] = "一幕深雾锁长江，难分渺茫。",
  ["~sk__godzhugeliang"] = "大业未竟，奈何天命将至……",
}

local godzhouyu = General(extension, "sk__godzhouyu", "god", 4)
local sk__qinyin = fk.CreateTriggerSkill{
  name = "sk__qinyin",
  anim_type = "control",
  events = {fk.EventPhaseChanging},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.to == Player.Discard
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = #room:askForDiscard(player, 2, 2, true, self.name, true, ".", "#sk__qinyin-discard")
    room:doIndicate(player.id, table.map(room.alive_players, Util.IdMapper))
    if n == 0 then
      player:drawCards(2, self.name)
      for _, p in ipairs(room:getAlivePlayers()) do
        if not p.dead then
          room:loseHp(p, 1, self.name)
        end
      end
    else
      for _, p in ipairs(room:getAlivePlayers()) do
        if not p.dead and p:isWounded() then
          room:recover({
            who = p,
            num = 1,
            recoverBy = player,
            skillName = self.name,
          })
        end
      end
    end
    if not player.dead and player:usedSkillTimes("sk__yeyan", Player.HistoryGame) > 0 and
      room:askForSkillInvoke(player, self.name, nil, "#sk__qinyin-invoke") then
      room:doIndicate(player.id, table.map(room.alive_players, Util.IdMapper))
      if n == 0 then
        for _, p in ipairs(room:getAlivePlayers()) do
          if not p.dead then
            room:loseHp(p, 1, self.name)
          end
        end
      else
        for _, p in ipairs(room:getAlivePlayers()) do
          if not p.dead and p:isWounded() then
            room:recover({
              who = p,
              num = 1,
              recoverBy = player,
              skillName = self.name,
            })
          end
        end
      end
    end
    return true
  end,
}
local sk__yeyan = fk.CreateActiveSkill{
  name = "sk__yeyan",
  anim_type = "offensive",
  frequency = Skill.Limited,
  min_card_num = 1,
  max_card_num = 4,
  target_num = 0,
  prompt = "#sk__yeyan",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter=function (self, to_select, selected, player)
    return #selected < 4 and not player:prohibitDiscard(to_select) and Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local red, black = 1, 1
    for _, id in ipairs(effect.cards) do
      if Fk:getCardById(id).color == Card.Red then
        red = red + 1
      elseif Fk:getCardById(id).color == Card.Black then
        black = black + 1
      end
    end
    room:throwCard(effect.cards, self.name, player, player)
    if player.dead then return end
    local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, black,
      "#sk__yeyan-choose:::"..black..":"..red, self.name, true)
    if #tos > 0 then
      room:sortPlayersByAction(tos)
      if red * #tos > 4 then
        room:loseHp(player, 3, self.name)
      end
      for _, id in ipairs(tos) do
        local p = room:getPlayerById(id)
        if not p.dead then
          room:damage{
            from = player,
            to = p,
            damage = red,
            damageType = fk.FireDamage,
            skillName = self.name,
          }
        end
      end
    end
  end
}
godzhouyu:addSkill(sk__qinyin)
godzhouyu:addSkill(sk__yeyan)
Fk:loadTranslationTable{
  ["sk__godzhouyu"] = "神周瑜",
  ["#sk__godzhouyu"] = "红莲业火",

  ["sk__qinyin"] = "琴音",
  [":sk__qinyin"] = "你可以跳过弃牌阶段，然后选择一项：1.摸两张牌，令所有角色各失去1点体力；2.弃置两张牌，令所有角色各回复1点体力。"..
  "然后若你发动过〖业炎〗，你可以选择再执行一次相同的失去或回复体力效果。",
  ["sk__yeyan"] = "业炎",
  [":sk__yeyan"] = "限定技，出牌阶段，你可以弃置至多四张手牌，然后对至多X+1名角色各造成Y+1点火焰伤害（X/Y为以此法弃置的黑色/红色牌数）。"..
  "若你以此法即将造成的总伤害不小于5点，你先失去3点体力。",
  ["#sk__qinyin-discard"] = "琴音：弃两张牌令所有角色回复1点体力，或点“取消”摸两张牌令所有角色失去1点体力",
  ["#sk__qinyin-invoke"] = "琴音：是否再执行一次失去/回复体力？",
  ["#sk__yeyan"] = "业炎：弃置至多四张手牌，对(黑色牌数+1)名角色各造成(红色牌数+1)点火焰伤害",
  ["#sk__yeyan-choose"] = "业炎：对至多%arg名角色各造成%arg2点火焰伤害！",

  ["$sk__qinyin1"] = "琴音其急，碎心裂胆。",
  ["$sk__qinyin2"] = "琴音其徐，如沐甘霖。",
  ["$sk__yeyan1"] = "红莲业火，焚尽人间！",
  ["$sk__yeyan2"] = "浮生罪业，皆归灰烬！",
  ["$sk__yeyan3"] = "血色火海，葬敌万千！",
  ["~sk__godzhouyu"] = "残焰黯然，玄歌不复！……",
}

local godliubei = General(extension, "sk__godliubei", "god", 4)
local sk__junwang = fk.CreateTriggerSkill{
  name = "sk__junwang",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart, fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target ~= player and target.phase == Player.Play and not target.dead and
      target:getHandcardNum() >= player:getHandcardNum() and not target:isKongcheng()
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {target.id})
    local cards = room:askForCard(target, 1, 1, false, self.name, false, ".", "#sk__junwang-give::"..player.id)
    room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonGive, self.name, nil, false, target.id)
  end,
}
local sk__jizhao = fk.CreateTriggerSkill{
  name = "sk__jizhao",
  anim_type = "support",
  events = {fk.EventPhaseStart, fk.DamageCaused, fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player.phase == Player.Play and not player:isKongcheng() and #player.room.alive_players > 1
      elseif event == fk.DamageCaused then
        return target and target:getMark("@sk__jizhao") > 0
      elseif event == fk.TurnStart then
        return target == player and table.find(player.room.alive_players, function (p)
          return p:getMark("@sk__jizhao") > 0
        end)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local result = room:askForYiji(player, player:getCardIds("h"), room:getOtherPlayers(player), self.name, 0, 999,
        "#sk__jizhao-give", nil, true)
      for _, ids in pairs(result) do
        if #ids > 0 then
          self.cost_data = result
          return true
        end
      end
    elseif event == fk.DamageCaused then
      return room:askForSkillInvoke(player, self.name, nil, "#sk__jizhao1-invoke:"..target.id..":"..data.to.id)
    elseif event == fk.TurnStart then
      return room:askForSkillInvoke(player, self.name, nil, "#sk__jizhao2-invoke")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local result = self.cost_data
      room:doYiji(result, player.id, self.name)
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if #result[tostring(p.id)] > 0 and not p.dead then
          room:addPlayerMark(p, "@sk__jizhao", 1)
        end
      end
    elseif event == fk.DamageCaused then
      room:removePlayerMark(target, "@sk__jizhao", 1)
      data.damage = data.damage + 1
    elseif event == fk.TurnStart then
      for _, p in ipairs(room:getAlivePlayers()) do
        local n = p:getMark("@sk__jizhao")
        if not p.dead and n > 0 then
          room:setPlayerMark(p, "@sk__jizhao", 0)
          room:loseHp(p, n, self.name)
        end
      end
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player and not table.find(player.room:getOtherPlayers(player), function(p)
      return p:hasSkill(self, true, true)
    end) then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAlivePlayers()) do
      room:setPlayerMark(p, "@sk__jizhao", 0)
    end
  end,
}
godliubei:addSkill(sk__junwang)
godliubei:addSkill(sk__jizhao)
Fk:loadTranslationTable{
  ["sk__godliubei"] = "神刘备",
  ["#sk__godliubei"] = "神龙之怒",

  ["sk__junwang"] = "君望",
  [":sk__junwang"] = "锁定技，其他角色出牌阶段开始时或结束时，若其手牌数不少于你，你令其交给你一张手牌。",
  ["sk__jizhao"] = "激诏",
  [":sk__jizhao"] = "出牌阶段开始时，你可以将任意张手牌分配给其他角色，以此法获得牌的角色获得1枚“激诏”标记。当拥有“激诏”标记的角色造成伤害时，"..
  "你可以弃置其1枚“激诏”标记，令此伤害+1。回合开始时，你可以弃置所有角色的“激诏”标记，令其失去等量的体力。",
  ["#sk__junwang-give"] = "君望：你需交给 %dest 一张手牌",
  ["@sk__jizhao"] = "激诏",
  ["#sk__jizhao-give"] = "激诏：你可以任意分配任意张手牌，获得牌的角色获得1枚“激诏”标记",
  ["#sk__jizhao1-invoke"] = "激诏：是否弃置 %src 一枚“激诏”标记，令其对 %dest 造成的伤害+1？",
  ["#sk__jizhao2-invoke"] = "激诏：是否弃置所有角色的“激诏”标记，令其失去等量的体力？",

  ["$sk__junwang1"] = "此诚危机存亡之时，当需一搏！",
  ["$sk__junwang2"] = "吾以汉室之名，借英雄一臂之力！",
  ["$sk__jizhao1"] = "破联盟，屠吴狗！",
  ["$sk__jizhao2"] = "不炬东吴，誓不为人！",
  ["~sk__godliubei"] = "朕今日，注定命丧此地……",
}

local godjiaxu = General(extension, "sk__godjiaxu", "god", 3)
local sk__yanmie = fk.CreateActiveSkill{
  name = "sk__yanmie",
  anim_type = "offensive",
  card_num = 1,
  target_num = 1,
  prompt = "#sk__yanmie",
  can_use = Util.TrueFunc,
  card_filter =function (self, to_select, selected, player)
    return #selected == 0 and Fk:getCardById(to_select).suit == Card.Spade and not player:prohibitDiscard(to_select)
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and to_select ~= player.id and not Fk:currentRoom():getPlayerById(to_select):isNude()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:throwCard(effect.cards, self.name, player, player)
    local cards = table.filter(target:getCardIds("he"), function(id)
      return not target:prohibitDiscard(id)
    end)
    if #cards == 0 then return end
    target:throwAllCards("he")
    if target.dead then return end
    cards = target:drawCards(#cards, self.name)
    if player.dead or target.dead then return end
    target:showCards(cards)
    if player.dead or target.dead then return end
    cards = table.filter(cards, function(id)
      return table.contains(target:getCardIds("h"), id) and Fk:getCardById(id).type ~= Card.TypeBasic
    end)
    if #cards == 0 then return end
    if room:askForSkillInvoke(player, self.name, nil, "#sk__yanmie-invoke::"..target.id..":"..#cards) then
      room:throwCard(cards, self.name, target, player)
      if not target.dead then
        room:damage({
          from = player,
          to = target,
          damage = #cards,
          skillName = self.name,
        })
      end
    end
  end,
}
local sk__shunshi = fk.CreateTriggerSkill{
  name = "sk__shunshi",
  anim_type = "control",
  events = {fk.TargetConfirming},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and (data.card.type == Card.TypeBasic or data.card:isCommonTrick()) and
      data.from ~= player.id and #AimGroup:getAllTargets(data.tos) == 1 and
      #player.room:getUseExtraTargets(data, true, true) > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local tos = room:askForChoosePlayers(player, room:getUseExtraTargets(data, true, true), 1, 3,
      "#sk__shunshi-choose:::"..data.card:toLogString(), self.name, true)
    if #tos > 0 then
      self.cost_data = tos
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:sortPlayersByAction(self.cost_data)
    for _, id in ipairs(self.cost_data) do
      AimGroup:addTargets(room, data, id)
    end
    player:drawCards(#self.cost_data, self.name)
  end,
}
godjiaxu:addSkill(sk__yanmie)
godjiaxu:addSkill(sk__shunshi)
Fk:loadTranslationTable{
  ["sk__godjiaxu"] = "神贾诩",
  ["#sk__godjiaxu"] = "谋定天下",

  ["sk__yanmie"] = "湮灭",
  [":sk__yanmie"] = "出牌阶段，你可以弃置一张♠牌并选择一名有牌的其他角色，其弃置所有牌，摸等量的牌并展示之，然后你可以弃置其中所有的非基本牌，"..
  "对其造成X点伤害（X为这些非基本牌的数量）。",
  ["sk__shunshi"] = "顺世",
  [":sk__shunshi"] = "当你成为其他角色使用的基本牌或普通锦囊牌的唯一目标时，你可以为此牌增加至多三名角色为目标，然后你摸X张牌（X为以此法增加的"..
  "目标数）。",
  ["#sk__yanmie"] = "湮灭：弃一张♠牌，令一名角色弃置所有牌、摸等量牌并展示",
  ["#sk__yanmie-invoke"] = "湮灭：是否令 %dest 弃置其中的非基本牌，对其造成%arg点伤害？",
  ["#sk__shunshi-choose"] = "顺世：你可以为此%arg增加至多三个目标，你摸等量的牌",

  ["$sk__yanmie1"] = "能救你的人，已经不在了。",
  ["$sk__yanmie2"] = "留你一命，用余生后悔去吧！",
  ["$sk__shunshi1"] = "死人，是不会说话的。",
  ["$sk__shunshi2"] = "此天意，非人力所能左右。",
  ["~sk__godjiaxu"] = "我死了，诸位就能幸免吗？哈哈哈哈哈……",
}

local godsunquan = General(extension, "sk__godsunquan", "god", 5)
local sk__huju = fk.CreateTriggerSkill{
  name = "sk__huju",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:drawCards(4, self.name)
    if target == player and not player.dead then
      room:changeMaxHp(player, -1)
      if player.dead then return end
      room:handleAddLoseSkills(player, "-sk__huju|ex__zhiheng|sk__xionglve|sk__hufu")
    end
  end,
}
local sk__hufu = fk.CreateActiveSkill{
  name = "sk__hufu",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#sk__hufu",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and to_select ~= player.id and #Fk:currentRoom():getPlayerById(to_select):getCardIds("e") > 0
  end,
  on_use = function(self, room, effect)
    local target = room:getPlayerById(effect.tos[1])
    local n = #target:getCardIds("e")
    room:askForDiscard(target, n, n, true, self.name, false)
  end,
}
godsunquan:addSkill(sk__huju)
godsunquan:addRelatedSkill("ex__zhiheng")
godsunquan:addRelatedSkill("sk__xionglve")
godsunquan:addRelatedSkill(sk__hufu)
Fk:loadTranslationTable{
  ["sk__godsunquan"] = "神孙权",
  ["#sk__godsunquan"] = "东吴大帝",

  ["sk__huju"] = "虎踞",
  [":sk__huju"] = "锁定技，一名角色回合开始时，你摸四张牌；若为你的回合，你减1点体力上限，失去〖虎踞〗，获得〖制衡〗〖雄略〗和〖虎缚〗。",
  ["sk__hufu"] = "虎缚",
  [":sk__hufu"] = "出牌阶段限一次，你可以令一名其他角色弃置X张牌（X为其装备区内的牌数）。",
  ["#sk__hufu"] = "虎缚：令一名角色弃置其装备区牌数的牌",

  ["$sk__huju1"] = "踞虎盘龙，步步为营。",
  ["$sk__huju2"] = "虎踞江东，立在鼎足。",
  ["$sk__huju3"] = "虎跃天堑，剑指中原。",
  ["$ex__zhiheng_sk__godsunquan"] = "大人虎变，其文炳也。",
  ["$sk__hufu1"] = "虎兕出柙，恩怨必报！",
  ["$sk__hufu2"] = "委肉虎蹊，祸必不振。",
  ["~sk__godsunquan"] = "效季良不得，陷为天下轻薄子……",
}

local goddiaochan = General(extension, "sk__goddiaochan", "god", 3, 3, General.Female)
local sk__tianzi = fk.CreateTriggerSkill{
  name = "sk__tianzi",
  frequency = Skill.Compulsory,
  anim_type = "drawcard",
  events = {fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and #player.room:getOtherPlayers(player) > 0
  end,
  on_use = function(self, event, target, player, data)
    data.n = data.n + #player.room:getOtherPlayers(player)
  end,
}
local sk__tianzi_maxcards = fk.CreateMaxCardsSkill{
  name = "#sk__tianzi_maxcards",
  frequency = Skill.Compulsory,
  main_skill = sk__tianzi,
  correct_func = function(self, player)
    if player:hasSkill(sk__tianzi) then
      return #table.filter(Fk:currentRoom().alive_players, function (p)
        return p ~= player
      end)
    end
  end,
}
local sk__meixin = fk.CreateActiveSkill{
  name = "sk__meixin",
  anim_type = "control",
  card_num = function ()
    return Self:getMark("sk__meixin")
  end,
  target_num = 1,
  prompt = function ()
    return "#sk__meixin:::"..Self:getMark("sk__meixin")
  end,
  can_use = Util.TrueFunc,
  card_filter =function (self, to_select, selected, player)
    return #selected < player:getMark("sk__meixin") and not player:prohibitDiscard(to_select)
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected == 0 and to_select ~= player.id then
      local target = Fk:currentRoom():getPlayerById(to_select)
      return target:isMale() and target:getMark("@@sk__meixin") == 0
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:setPlayerMark(target, "@@sk__meixin", 1)
    room:throwCard(effect.cards, self.name, player, player)
  end,
}
local sk__meixin_trigger = fk.CreateTriggerSkill{
  name = "#sk__meixin_trigger",
  mute = true,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return target == player and (player:hasSkill(sk__meixin) or player:isFemale()) and
      table.find(player.room.alive_players, function (p)
        return p:getMark("@@sk__meixin") > 0
      end)
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("sk__meixin")
    if data.card.type == Card.TypeEquip then
      room:notifySkillInvoked(player, "sk__meixin", "offensive")
      for _, p in ipairs(room:getAllPlayers()) do
        if p:getMark("@@sk__meixin") > 0 and not p.dead then
          room:doIndicate(player.id, {p.id})
          room:damage({
            from = player,
            to = p,
            damage = 1,
            skillName = "sk__meixin",
          })
        end
      end
    else
      room:notifySkillInvoked(player, "sk__meixin", "control")
      for _, p in ipairs(room:getAllPlayers()) do
        if player.dead then return end
        if p:getMark("@@sk__meixin") > 0 and not p.dead then
          room:doIndicate(player.id, {p.id})
          if not p:isNude() then
            if data.card.type == Card.TypeBasic then
              local card = room:askForCardChosen(player, p, "he", "sk__meixin", "#sk__meixin-discard::"..p.id)
              room:throwCard(card, "sk__meixin", p, player)
            elseif data.card.type == Card.TypeTrick then
              local card = room:askForCardChosen(player, p, "he", "sk__meixin", "#sk__meixin-prey::"..p.id)
              room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonPrey, "sk__meixin", nil, false, player.id)
            end
          end
        end
      end
    end
  end,

  refresh_events = {fk.StartPlayCard, fk.TurnStart},
  can_refresh = function (self, event, target, player, data)
    if target == player then
      if event == fk.StartPlayCard then
        return player:hasSkill(sk__meixin, true)
      else
        return player:getMark("@@sk__meixin") > 0
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    if event == fk.StartPlayCard then
      local n = #table.filter(room.alive_players, function (p)
        return p:getMark("@@sk__meixin") > 0
      end)
      room:setPlayerMark(player, "sk__meixin", n + 1)
    else
      room:setPlayerMark(player, "@@sk__meixin", 0)
    end
  end,
}
sk__tianzi:addRelatedSkill(sk__tianzi_maxcards)
sk__meixin:addRelatedSkill(sk__meixin_trigger)
goddiaochan:addSkill(sk__tianzi)
goddiaochan:addSkill(sk__meixin)
Fk:loadTranslationTable{
  ["sk__goddiaochan"] = "神貂蝉",
  ["#sk__goddiaochan"] = "绝代风华",

  ["sk__tianzi"] = "天姿",
  [":sk__tianzi"] = "锁定技，摸牌阶段，你额外摸X张牌；你的手牌上限+X。（X为存活的其他角色数）",
  ["sk__meixin"] = "魅心",
  [":sk__meixin"] = "出牌阶段，你可以弃置X张牌并选择一名未拥有“魅心”标记的其他男性角色（X为拥有“魅心”标记的角色数+1），令其获得1枚“魅心”"..
  "标记直到其下回合开始。当你或任意女性角色使用牌后，根据使用牌的类别，对拥有“魅心”标记的角色依次执行效果：<br>"..
  "基本牌，弃置其一张牌；<br>锦囊牌，获得其一张牌；<br>装备牌，对其造成1点伤害。",
  ["#sk__meixin"] = "魅心：弃置%arg张牌，选择一名男性角色，女性角色使用牌后根据类别对其产生效果",
  ["@@sk__meixin"] = "魅心",
  ["#sk__meixin_trigger"] = "魅心",
  ["#sk__meixin-discard"] = "魅心：弃置 %dest 一张牌",
  ["#sk__meixin-prey"] = "魅心：获得 %dest 一张牌",

  ["$sk__tianzi"] = "香囊暗解，罗带轻分，薄幸谁常往？",
  ["$sk__meixin1"] = "夫为乐，为乐当及时。",
  ["$sk__meixin2"] = "滔滔日夜东注，多少醉生梦死。",
  ["$sk__meixin3"] = "银壶金樽复美酒，与君同销万古愁。",
  ["$sk__meixin4"] = "妾心妾意，唯愿长相伴。",
  ["~sk__goddiaochan"] = "自古美人如名将，不许人间见白头。",
}

local godzhangfei = General(extension, "sk__godzhangfei", "god", 4)
local sk__shayi = fk.CreateViewAsSkill{
  name = "sk__shayi",
  prompt = "#sk__shayi",
  card_filter = function(self, to_select, selected)
    local card = Fk:getCardById(to_select)
    return #selected == 0 and card.color == Card.Black and card:getMark("@@sk__shayi-phase") > 0
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return nil end
    local card = Fk:cloneCard("slash")
    card:addSubcard(cards[1])
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player, use)
    player:drawCards(1, self.name)
  end,
  enabled_at_play = function(self, player)
    return player:usedSkillTimes("sk__shayi", Player.HistoryPhase) > 0 and
      table.find(player:getCardIds("h"), function(id)
        return Fk:getCardById(id):getMark("@@sk__shayi-phase") > 0 end)
  end,
}
local sk__shayi_trigger = fk.CreateTriggerSkill{
  name = "#sk__shayi_trigger",
  mute = true,
  frequency = Skill.Compulsory,
  main_skill = sk__shayi,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(sk__shayi) and player.phase == Player.Play
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("sk__shayi")
    room:notifySkillInvoked(player, "sk__shayi", "special")
    player:drawCards(1, "sk__shayi")
    local cards = table.simpleClone(player:getCardIds("h"))
    if not player.dead and not player:isKongcheng() then
      room:setPlayerMark(player, "sk__shayi-phase", cards)
      for _, id in ipairs(cards) do
        if Fk:getCardById(id).color == Card.Black then
          room:setCardMark(Fk:getCardById(id, true), "@@sk__shayi-phase", 1)
        end
      end
    end
  end,

  refresh_events = {fk.AfterCardsMove, fk.Death},
  can_refresh = function(self, event, target, player, data)
    if player:getMark("sk__shayi-phase") ~= 0 then
      if event == fk.AfterCardsMove then
        return true
      else
        return player == target
      end
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getMark("sk__shayi-phase")
    if event == fk.AfterCardsMove then
      for _, move in ipairs(data) do
        if move.toArea ~= Card.Processing then
          for _, info in ipairs(move.moveInfo) do
            table.removeOne(mark, info.cardId)
            room:setCardMark(Fk:getCardById(info.cardId), "@@sk__shayi-phase", 0)
          end
        end
      end
      room:setPlayerMark(player, "sk__shayi-phase", mark)
    elseif event == fk.Death then
      for _, id in ipairs(mark) do
        room:setCardMark(Fk:getCardById(id), "@@sk__shayi-phase", 0)
      end
    end
  end,
}
local sk__shayi_targetmod = fk.CreateTargetModSkill{
  name = "#sk__shayi_targetmod",
  main_skill = sk__shayi,
  frequency = Skill.Compulsory,
  bypass_times = function(self, player, skill, scope, card, to)
    return player:hasSkill(sk__shayi) and skill.trueName == "slash_skill"
  end,
  bypass_distances =  function(self, player, skill, card, to)
    return player:hasSkill(sk__shayi) and skill.trueName == "slash_skill"
  end,
}
local sk__zhenhun = fk.CreateActiveSkill{
  name = "sk__zhenhun",
  mute = true,
  card_num = 0,
  target_num = 0,
  prompt = "#sk__zhenhun",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    player:broadcastSkillInvoke(self.name)
    room:notifySkillInvoked(player, self.name, "big")
    local targets = room:getOtherPlayers(player)
    room:doIndicate(player.id, table.map(targets, Util.IdMapper))
    for _, target in ipairs(targets) do
      room:setPlayerMark(target, "@@sk__zhenhun-phase", 1)
    end
  end,
}
local sk__zhenhun_invalidity = fk.CreateInvaliditySkill {
  name = "#sk__zhenhun_invalidity",
  invalidity_func = function(self, from, skill)
    return from:getMark("@@sk__zhenhun-phase") > 0 and
      skill.frequency ~= Skill.Compulsory and skill.frequency ~= Skill.Wake and
      skill:isPlayerSkill(from)
  end
}
local sk__zhenhun_prohibit = fk.CreateProhibitSkill{
  name = "#sk__zhenhun_prohibit",
  prohibit_use = function(self, player, card)
    return player:getMark("@@sk__zhenhun-phase") > 0 and card and card.name == "peach" and not player.dying
  end,
}
sk__shayi:addRelatedSkill(sk__shayi_trigger)
sk__shayi:addRelatedSkill(sk__shayi_targetmod)
sk__zhenhun:addRelatedSkill(sk__zhenhun_invalidity)
sk__zhenhun:addRelatedSkill(sk__zhenhun_prohibit)
godzhangfei:addSkill(sk__shayi)
godzhangfei:addSkill(sk__zhenhun)
Fk:loadTranslationTable{
  ["sk__godzhangfei"] = "神张飞",
  ["#sk__godzhangfei"] = "",

  ["sk__shayi"] = "杀意",
  [":sk__shayi"] = "锁定技，你使用【杀】无距离次数限制。出牌阶段开始时，你摸一张牌并标记手牌中的黑色牌，你于此阶段内可以将这些牌当【杀】"..
  "使用并摸一张牌。",
  ["sk__zhenhun"] = "震魂",
  [":sk__zhenhun"] = "出牌阶段限一次，你可以令所有其他角色的非锁定技失效、不处于濒死状态不能使用【桃】，直到本阶段结束。",
  ["#sk__shayi"] = "杀意：你可以将“杀意”牌当【杀】使用并摸一张牌",
  ["@@sk__shayi-phase"] = "杀意",
  ["#sk__zhenhun"] = "震魂：令所有其他角色本阶段非锁定技失效、不处于濒死状态不能使用【桃】！",
  ["@@sk__zhenhun-phase"] = "震魂",

  ["$sk__shayi1"] = "长矛所向，万夫不当！",
  ["$sk__shayi2"] = "呆若木鸡，是等死吗！",
  ["$sk__shayi3"] = "喝啊！！！",
  ["$sk__shayi4"] = "看爷爷我大杀四方！",
  ["$sk__zhenhun"] = "都跪下，叫老子一声爹！",
  ["~sk__godzhangfei"] = "汝等杂碎！还吾头来……",
}

local godsimahui = General(extension, "sk__godsimahui", "god", 3)
local sk__yinshi = fk.CreateTriggerSkill{
  name = "sk__yinshi",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(data.damage, self.name)
    if data.damageType ~= fk.ThunderDamage then
      return true
    end
  end,
}
local sk__zhitian = fk.CreateTriggerSkill{
  name = "sk__zhitian",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Start
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local generals = room:getNGenerals(3)
    if #generals == 0 then return end
    local skills = {}
    for i = 1, #generals, 1 do
      table.insert(skills, Fk.generals[generals[i]]:getSkillNameList(true))
    end
    local result = room:askForCustomDialog(player, self.name,
      "packages/jilvRem/qml/ChooseGeneralSkillsBox.qml", {
      generals, skills, 1, 1, "#sk__zhitian-choice", false
    })
    room:returnToGeneralPile(generals)
    local skill = skills[1][1]
    if result ~= "" then
      skill = json.decode(result)[1]
    end
    local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
      "#sk__zhitian-choose:::"..skill, self.name, false)
    to = room:getPlayerById(to[1])
    if to ~= player and not player:isKongcheng() then
      room:moveCardTo(player:getCardIds("h"), Card.PlayerHand, to, fk.ReasonGive, self.name, nil, false, player.id)
    end
    if not to.dead then
      room:handleAddLoseSkills(to, skill, nil, true, false)
    end
    if not to.dead then
      room:loseHp(to, 1, self.name)
    end
  end,
}
godsimahui:addSkill(sk__yinshi)
godsimahui:addSkill(sk__zhitian)
Fk:loadTranslationTable{
  ["sk__godsimahui"] = "神司马徽",
  ["#sk__godsimahui"] = "局中窥人",

  ["sk__yinshi"] = "隐世",
  [":sk__yinshi"] = "锁定技，当你受到伤害时，你摸X张牌（X为伤害值），然后若此伤害不为雷电伤害，防止此伤害。",
  ["sk__zhitian"] = "知天",
  [":sk__zhitian"] = "锁定技，准备阶段，你随机展示三张武将牌并选择其中一个技能，然后选择一名角色，你将所有手牌交给该角色，其获得此技能并"..
  "失去1点体力。",
  ["#sk__zhitian-choice"] = "知天：请选择一个技能",
  ["#sk__zhitian-choose"] = "知天：选择一名角色，将所有手牌交给其、令其获得〖%arg〗并失去1点体力",

  ["$sk__yinshi"] = "逃遁避世，虽逢无道，心无所闷。",
  ["$sk__zhitian"] = "见龙在田，利见大人。",
  ["~sk__godsimahui"] = "万物顺应承天，老夫自当归去……",
}

local godganning = General(extension, "sk__godganning", "god", 4)
local sk__lvezhen = fk.CreateTriggerSkill{
  name = "sk__lvezhen",
  anim_type = "offensive",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and (data.card.trueName == "slash" or data.card.type == Card.TypeTrick) and
      #AimGroup:getAllTargets(data.tos) == 1 and data.to ~= player.id and player.phase == Player.Play and
      not player.room:getPlayerById(AimGroup:getAllTargets(data.tos)[1]):isNude() and
      player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#sk__lvezhen-invoke::"..data.to)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.to)
    room:doIndicate(player.id, {data.to})
    room:moveCardTo(table.random(to:getCardIds("he")), Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
  end,
}
local sk__youlong = fk.CreateTriggerSkill{
  name = "sk__youlong",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.BeforeTurnOver, fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.BeforeTurnOver then
        return target == player and not player.faceup
      elseif event == fk.TurnEnd then
        return target ~= player
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.BeforeTurnOver then
      return true
    else
      player:broadcastSkillInvoke(self.name)
      player.room:notifySkillInvoked(player, self.name, "special")
      player:drawCards(1, self.name)
      player:gainAnExtraPhase(Player.Play, true)
    end
  end,

  refresh_events = {fk.EventAcquireSkill},
  can_refresh = function (self, event, target, player, data)
    return target == player and data == self and player.faceup
  end,
  on_refresh = function (self, event, target, player, data)
    player:turnOver()
  end,
}
godganning:addSkill(sk__lvezhen)
godganning:addSkill(sk__youlong)
Fk:loadTranslationTable{
  ["sk__godganning"] = "神甘宁",
  ["#sk__godganning"] = "披星破浪",

  ["sk__lvezhen"] = "掠阵",
  [":sk__lvezhen"] = "你的出牌阶段内限一次，当你使用【杀】或锦囊牌指定唯一目标后，你可以随机获得其一张牌。",
  ["sk__youlong"] = "游龙",
  [":sk__youlong"] = "锁定技，你始终背面朝上。其他角色回合结束时，你摸一张牌并执行一个额外的出牌阶段。",
  ["#sk__lvezhen-invoke"] = "掠阵：是否随机获得 %dest 一张牌？",

  ["$sk__lvezhen1"] = "天不怕，掠阵杀人！",
  ["$sk__lvezhen2"] = "地不荒，攻池破城！",
  ["$sk__youlong1"] = "轻甲刀，拿人头！",
  ["$sk__youlong2"] = "游龙手，夺绣花！",
  ["~sk__godganning"] = "哼，江东好汉，誓死不降！",
}

local goddianwei = General(extension, "sk__goddianwei", "god", 5)
local sk__zhiji = fk.CreateActiveSkill{
  name = "sk__zhiji",
  anim_type = "offensive",
  min_card_num = 1,
  min_target_num = 1,
  prompt = "#sk__zhiji",
  can_use = function(self, player)
    return player:getMark("sk__zhiji-phase") == 0
  end,
  card_filter =function (self, to_select, selected, player)
    return Fk:getCardById(to_select).sub_type == Card.SubtypeWeapon and not player:prohibitDiscard(Fk:getCardById(to_select))
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected < #selected_cards and to_select ~= player.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:setPlayerMark(player, "sk__zhiji-phase", 1)
    room:sortPlayersByAction(effect.tos)
    local targets = table.map(effect.tos, Util.Id2PlayerMapper)
    room:throwCard(effect.cards, self.name, player, player)
    for _, target in ipairs(targets) do
      if not target.dead then
        room:damage{
          from = player,
          to = target,
          damage = #effect.cards,
          skillName = self.name,
        }
      end
    end
  end,
}
local sk__zhiji_trigger = fk.CreateTriggerSkill{
  name = "#sk__zhiji_trigger",
  mute = true,
  main_skill = sk__zhiji,
  events = {fk.EventPhaseStart, fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(sk__zhiji) then
      if event == fk.EventPhaseStart then
        return player.phase == Player.Start and player:isWounded()
      else
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, "sk__zhiji", nil)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = table.filter(room.draw_pile, function(id)
      return Fk:getCardById(id).sub_type == Card.SubtypeWeapon
    end)
    table.insertTable(cards, table.filter(room.discard_pile, function(id)
      return Fk:getCardById(id).sub_type == Card.SubtypeWeapon
    end))
    for _, p in ipairs(room.alive_players) do
      table.insertTable(cards, table.filter(p:getCardIds("e"), function(id)
        return Fk:getCardById(id).sub_type == Card.SubtypeWeapon
      end))
    end
    if #cards == 0 then return end
    room:moveCardTo(table.random(cards), Card.PlayerHand, player, fk.ReasonPrey, "sk__zhiji", nil, true, player.id)
    if player.dead or player:isKongcheng() then return end
    cards = table.filter(player:getCardIds("h"), function(id)
      return Fk:getCardById(id).type ~= Card.TypeEquip
    end)
    if #cards == 0 then return end
    room:askForDiscard(player, 1, 1, true, "sk__zhiji", false, ".|.|.|.|.|^equip", "#sk__zhiji-discard")
  end,
}
sk__zhiji:addRelatedSkill(sk__zhiji_trigger)
goddianwei:addSkill(sk__zhiji)
Fk:loadTranslationTable{
  ["sk__goddianwei"] = "神典韦",
  ["#sk__goddianwei"] = "无双乱戟",

  ["sk__zhiji"] = "掷戟",
  [":sk__zhiji"] = "出牌阶段限一次，你可以弃置任意张武器牌，然后对至多等量的其他角色各造成等量的伤害。<br>准备阶段，若你已受伤，或当你"..
  "受到伤害后，你可以从场上、牌堆或弃牌堆随机获得一张武器牌，然后弃置一张非装备牌。",
  ["#sk__zhiji"] = "掷戟：弃置X张武器牌，对至多X名角色各造成X点伤害！",
  ["#sk__zhiji_trigger"] = "掷戟",
  ["#sk__zhiji-discard"] = "掷戟：请弃置一张非装备牌",

  ["$sk__zhiji1"] = "恶来之力，助我神威！",
  ["$sk__zhiji2"] = "铁戟出，地狱开！",
  ["$sk__zhiji3"] = "这一击，定让你魂飞魄散！",
  ["$sk__zhiji4"] = "这天下，没有我拿不动的兵器！",
  ["~sk__goddianwei"] = "主公安然，未将死而无憾……",
}

local godxiahoudun = General(extension, "sk__godxiahoudun", "god", 5)
local sk__danjing = fk.CreateTriggerSkill{
  name = "sk__danjing",
  anim_type = "offensive",
  events = {fk.Damaged, fk.HpLost, fk.MaxHpChanged, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.AfterCardsMove then
        local n = 0
        for _, move in ipairs(data) do
          if move.from and move.from == player.id and move.toArea == Card.DiscardPile and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                n = n + 1
              end
            end
          end
        end
        if n > 0 and table.find(player.room:getOtherPlayers(player), function (p)
          return not p:isNude()
        end) then
          self.cost_data = n
          return true
        end
      elseif target == player and #player.room.alive_players > 0 then
        if event == fk.Damaged then
          self.cost_data = data.damage
          return true
        elseif event == fk.HpLost then
          self.cost_data = data.num
          return true
        elseif event == fk.MaxHpChanged and data.num < 0 then
          self.cost_data = -data.num
          return true
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(room:getOtherPlayers(player), Util.IdMapper)
    local prompt
    if event == fk.AfterCardsMove then
      targets = table.map(table.filter(room:getOtherPlayers(player), function(p)
        return not p:isNude()
      end), Util.IdMapper)
      prompt = 4
    elseif event == fk.Damaged then
      prompt = 1
    elseif event == fk.HpLost then
      prompt = 2
    elseif event == fk.MaxHpChanged then
      prompt = 3
    end
    local to = room:askForChoosePlayers(player, targets, 1, 1,
      "#sk__danjing"..prompt.."-choose:::"..self.cost_data, self.name, true, false)
    if #to > 0 then
      self.cost_data = {to[1], self.cost_data}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data[1])
    local n = self.cost_data[2]
    if event == fk.Damaged then
      room:damage{
        from = player,
        to = to,
        damage = data.damage,
        damageType = data.damageType,
        skillName = self.name,
      }
    elseif event == fk.HpLost then
      room:loseHp(to, data.num, self.name)
    elseif event == fk.MaxHpChanged then
      room:changeMaxHp(to, data.num)
    elseif event == fk.AfterCardsMove then
      room:askForDiscard(to, n, n, true, self.name, false)
    end
  end,
}
local sk__zhonghun = fk.CreateActiveSkill{
  name = "sk__zhonghun",
  anim_type = "defensive",
  frequency = Skill.Limited,
  card_num = 0,
  target_num = 1,
  prompt = "#sk__zhonghun-choose",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and to_select ~= player.id
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:changeMaxHp(player, -1)
    if target.dead then return end
    room:changeMaxHp(target, 1)
    if target.dead then return end
    if target:isWounded() then
      room:recover({
        who = target,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      })
    end
    if player.dead then return end
    room:setPlayerMark(player, "@sk__zhonghun", target.general)
    room:setPlayerMark(player, self.name, target.id)
  end,
}
local sk__zhonghun_trigger = fk.CreateTriggerSkill{
  name = "#sk__zhonghun_trigger",
  mute = true,
  main_skill = sk__zhonghun,
  events = {fk.GameStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(sk__zhonghun) and #player.room.alive_players > 1 and
      player:usedSkillTimes("sk__zhonghun", Player.HistoryGame) == 0
  end,
  on_cost = function (self, event, target, player, data)
    local to = player.room:askForChoosePlayers(player, table.map(player.room:getOtherPlayers(player), Util.IdMapper), 1, 1,
      "#sk__zhonghun-choose", "sk__zhonghun", true, false)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("sk__zhonghun")
    room:notifySkillInvoked(player, "sk__zhonghun")
    sk__zhonghun:onUse(room, {
      from = player.id,
      tos = {self.cost_data},
    })
  end,
}
local sk__zhonghun_delay = fk.CreateTriggerSkill{
  name = "#sk__zhonghun_delay",
  mute = true,
  events = {fk.DamageInflicted, fk.Death},
  can_trigger = function(self, event, target, player, data)
    if player:getMark("sk__zhonghun") ~= 0 then
      if event == fk.DamageInflicted then
        return player:getMark("sk__zhonghun") == target.id and (not data.from or data.from ~= player)
      else
        return target == player and not player.room:getPlayerById(player:getMark("sk__zhonghun")).dead
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("sk__zhonghun")
    room:notifySkillInvoked(player, "sk__zhonghun", "defensive")
    if event == fk.DamageInflicted then
      local new_data = table.simpleClone(data)
      new_data.to = player
      room:damage(new_data)
      return true
    else
      local to = room:getPlayerById(player:getMark("sk__zhonghun"))
      room:doIndicate(player.id, {to.id})
      local skills = {}
      for _, s in ipairs(player.player_skills) do
        if s:isPlayerSkill(player) and s.visible and not to:hasSkill(s, true) then
          table.insert(skills, s.name)
        end
      end
      room:handleAddLoseSkills(to, skills, nil, true, false)
    end
  end,

  refresh_events = {fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    return player:usedSkillTimes("sk__zhonghun", Player.HistoryGame) > 0 and player:getMark("sk__zhonghun") == target.id
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "@sk__zhonghun", 0)
    player.room:setPlayerMark(player, "sk__zhonghun", 0)
  end,
}
sk__zhonghun:addRelatedSkill(sk__zhonghun_trigger)
sk__zhonghun:addRelatedSkill(sk__zhonghun_delay)
godxiahoudun:addSkill(sk__danjing)
godxiahoudun:addSkill(sk__zhonghun)
Fk:loadTranslationTable{
  ["sk__godxiahoudun"] = "神夏侯惇",
  ["#sk__godxiahoudun"] = "不灭忠侯",

  ["sk__danjing"] = "啖睛",
  [":sk__danjing"] = "当你受到伤害后/失去体力后/扣减体力上限后/弃置牌后，你可以令一名其他角色也执行相同的效果。",
  ["sk__zhonghun"] = "忠魂",
  [":sk__zhonghun"] = "限定技，游戏开始时，或出牌阶段，你可以减1点体力上限并选择一名其他角色，令其加1点体力上限并回复1点体力。"..
  "若如此做，本局游戏当其受到伤害时，若伤害来源不为你，将此伤害转移给你；当你死亡时，其获得你所有技能。",
  ["#sk__danjing1-choose"] = "啖睛：你可以对一名角色造成%arg点伤害",
  ["#sk__danjing2-choose"] = "啖睛：你可以令一名角色失去%arg点体力",
  ["#sk__danjing3-choose"] = "啖睛：你可以令一名角色减%arg点体力上限",
  ["#sk__danjing4-choose"] = "啖睛：你可以令一名角色弃置%arg张牌",
  ["#sk__zhonghun-choose"] = "忠魂：选择一名角色，其本局受到的伤害均转移给你！",
  ["@sk__zhonghun"] = "忠魂",

  ["$sk__danjing1"] = "我看见你了！",
  ["$sk__danjing2"] = "想走？把人头留下！",
  ["$sk__danjing3"] = "父精母血，不可弃之！",
  ["$sk__zhonghun1"] = "都等什么？继续冲！",
  ["$sk__zhonghun2"] = "还没分出胜负！",
  ["~sk__godxiahoudun"] = "我要亲自……向丞相谢罪……",
}

local godsunshangxiang = General(extension, "sk__godsunshangxiang", "god", 3, 3, General.Female)
local sk__xianzhu = fk.CreateTriggerSkill{
  name = "sk__xianzhu",
  anim_type = "support",
  events = {fk.HpRecover, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.HpRecover then
        self.cost_data = target
        return not target.dead
      elseif event == fk.AfterCardsMove then
        for _, move in ipairs(data) do
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerEquip and not player.room:getPlayerById(move.from).dead then
              return true
            end
          end
        end
      end
    end
  end,
  on_trigger = function(self, event, target, player, data)
    if event == fk.HpRecover then
      self.cost_data = target.id
      self:doCost(event, target, player, data)
    elseif event == fk.AfterCardsMove then
      local targets = {}
      for _, move in ipairs(data) do
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerEquip then
            table.insertIfNeed(targets, move.from)
          end
        end
      end
      player.room:sortPlayersByAction(targets)
      for _, id in ipairs(targets) do
        if not player:hasSkill(self) then return end
        if not player.room:getPlayerById(id).dead then
          self.cost_data = id
          self:doCost(event, target, player, data)
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#sk__xianzhu-invoke::"..self.cost_data)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {self.cost_data})
    room:getPlayerById(self.cost_data):drawCards(2, self.name)
  end,
}
local sk__liangyuan = fk.CreateActiveSkill{
  name = "sk__liangyuan",
  anim_type = "support",
  frequency = Skill.Limited,
  prompt = "#sk__liangyuan",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and to_select ~= player.id and Fk:currentRoom():getPlayerById(to_select).gender == General.Male
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:setPlayerMark(player, "@sk__liangyuan", target.general)
    room:setPlayerMark(player, self.name, target.id)
  end,
}
local sk__liangyuan_delay = fk.CreateTriggerSkill{
  name = "#sk__liangyuan_delay",
  mute = true,
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:usedSkillTimes("sk__liangyuan", Player.HistoryGame) > 0 and
     not player:insideExtraTurn() and not player.room:getPlayerById(player:getMark("sk__liangyuan")).dead
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player.room:getPlayerById(player:getMark("sk__liangyuan")):gainAnExtraTurn(true, "sk__liangyuan")
  end,
}
sk__liangyuan:addRelatedSkill(sk__liangyuan_delay)
godsunshangxiang:addSkill(sk__xianzhu)
godsunshangxiang:addSkill(sk__liangyuan)
Fk:loadTranslationTable{
  ["sk__godsunshangxiang"] = "神孙尚香",
  ["#sk__godsunshangxiang"] = "弓马枭姬",

  ["sk__xianzhu"] = "贤助",
  [":sk__xianzhu"] = "当一名角色回复体力后，或当一名角色失去装备区内的牌后，你可以令其摸两张牌。",
  ["sk__liangyuan"] = "良缘",
  [":sk__liangyuan"] = "限定技，出牌阶段，你可以选择一名其他男性角色，本局游戏你的非额外回合结束后，其进行一个额外的回合。",
  ["#sk__xianzhu-invoke"] = "贤助：是否令 %dest 摸两张牌？",
  ["#sk__liangyuan"] = "良缘：选择一名男性角色，本局游戏你的非额外回合结束后，其进行一个额外回合！",
  ["@sk__liangyuan"] = "良缘",

  ["$sk__xianzhu1"] = "春风复多情，吹我罗裳开。",
  ["$sk__xianzhu2"] = "春林花多媚，春鸟意多哀。",
  ["$sk__liangyuan"] = "我心如松柏，君情复何似？",
  ["~sk__godsunshangxiang"] = "夫君，你可会记得我的好？",
}

local godhuatuo = General(extension, "sk__godhuatuo", "god", 3)
local sk__yuanhua = fk.CreateTriggerSkill{
  name = "sk__yuanhua",
  anim_type = "support",
  frequency = Skill.Compulsory,
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      for _, move in ipairs(data) do
        if move.to == player.id and move.toArea == Card.PlayerHand then
          for _, info in ipairs(move.moveInfo) do
            if Fk:getCardById(info.cardId).trueName == "peach" then
              return true
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player:isWounded() then
      room:recover({
        who = player,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      })
    end
    if not player.dead then
      player:drawCards(2, self.name)
    end
    local cards = {}
    for _, move in ipairs(data) do
      if move.to == player.id and move.toArea == Card.PlayerHand then
        for _, info in ipairs(move.moveInfo) do
          if Fk:getCardById(info.cardId).trueName == "peach" and table.contains(player:getCardIds("h"), info.cardId) then
            table.insertIfNeed(cards, info.cardId)
          end
        end
      end
    end
    if #cards > 0 then
      room:addPlayerMark(player, self.name, #cards)
      room:moveCardTo(cards, Card.Void, nil, fk.ReasonJustMove, self.name, nil, true, player.id)
    end
  end,
}
local sk__guiyuan = fk.CreateActiveSkill{
  name = "sk__guiyuan",
  anim_type = "control",
  card_num = 0,
  target_num = 0,
  prompt = "#sk__guiyuan",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:loseHp(player, 1, self.name)
    if player.dead then return end
    local targets = room:getOtherPlayers(player)
    room:doIndicate(player.id, table.map(targets, Util.IdMapper))
    for _, target in ipairs(targets) do
      if player.dead then return end
      if not target.dead then
        local card = room:askForCard(target, 1, 1, false, self.name, true, "peach", "#sk__guiyuan-give:"..player.id)
        if #card == 0 then
          local cards = table.filter(target:getCardIds("h"), function (id)
            return Fk:getCardById(id).trueName == "peach"
          end)
          if #cards > 0 then
            card = table.random(cards, 1)
          end
        end
        if #card > 0 then
          room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonGive, self.name, nil, true, target.id)
        end
      end
    end
    if not player.dead then
      local cards = room:getCardsFromPileByRule("peach", 1, "allPiles")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
      end
    end
  end,
}
local sk__chongsheng = fk.CreateTriggerSkill{
  name = "sk__chongsheng",
  anim_type = "support",
  frequency = Skill.Limited,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and not target.dead and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, data,
      "#sk__chongsheng-invoke::"..target.id..":"..math.max(player:getMark("sk__yuanhua"), 1))
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {target.id})
    local n = math.max(player:getMark("sk__yuanhua"), 1)
    if n ~= target.maxHp then
      room:changeMaxHp(target, n - target.maxHp)
    end
    if not target.dead and target:isWounded() then
      room:recover{
        who = target,
        num = target:getLostHp(),
        recoverBy = player,
        skillName = self.name,
      }
    end
    if not target.dead then
      local generals = room:findGenerals(function(g)
        return Fk.generals[g].kingdom == target.kingdom
      end, 3)
      if #generals == 0 then return end
      local result = room:askForCustomDialog(target, self.name, "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml", {
        generals,
        {"OK"},
        "#sk__chongsheng-choose",
        {"Cancel"},
      })
      local general = ""
      if result == "" then
        return
      else
        local reply = json.decode(result)
        if reply.choice == "OK" then
          general = reply.cards[1]
        else
          return
        end
      end
      table.removeOne(generals, general)
      room:returnToGeneralPile(generals)
      room:changeHero(target, general, false, false, true, false)
    end
  end,
}
godhuatuo:addSkill(sk__yuanhua)
godhuatuo:addSkill(sk__guiyuan)
godhuatuo:addSkill(sk__chongsheng)
Fk:loadTranslationTable{
  ["sk__godhuatuo"] = "神华佗",
  ["#sk__godhuatuo"] = "悬壶济世",

  ["sk__yuanhua"] = "元化",
  [":sk__yuanhua"] = "锁定技，当你获得【桃】后，你回复1点体力并摸两张牌，然后将之移出游戏。",
  ["sk__guiyuan"] = "归元",
  [":sk__guiyuan"] = "出牌阶段限一次，你可以失去1点体力，令所有其他角色各交给你一张【桃】，然后你从牌堆或弃牌堆获得一张【桃】。",
  ["sk__chongsheng"] = "重生",
  [":sk__chongsheng"] = "限定技，当一名角色进入濒死状态时，你可以令其将体力上限调整至X并回复体力至体力上限（X为你发动〖元化〗移出游戏的牌数，"..
  "至少为1），然后其可以从随机三张未加入游戏的其当前势力的武将牌中选择一张替换其武将。",
  ["#sk__guiyuan"] = "归元：失去1点体力，令所有角色各交给你一张【桃】，然后你从牌堆或弃牌堆获得一张【桃】",
  ["#sk__guiyuan-give"] = "归元：请交给 %src 一张【桃】",
  ["#sk__chongsheng-invoke"] = "重生：是否令 %dest 回复体力和体力上限至%arg并更换武将？",
  ["#sk__chongsheng-choose"] = "重生：你可以变身为另一名武将！",

  ["$sk__yuanhua1"] = "怎么样，是不是感觉好点了？",
  ["$sk__yuanhua2"] = "两剂服下，自当痊愈。",
  ["$sk__guiyuan"] = "这点小技艺，怕不足以救天下人吧。",
  ["$sk__chongsheng"] = "快好起来吧，还有人等着你。",
  ["~sk__godhuatuo"] = "别担心，毕竟，也这个岁数了……",
}

local sp_godzhugeliang = General(extension, "sk_sp__godzhugeliang", "god", 7)
local function getYaozhiSkills(player, event)
  local list = {
    ["phase_start"] = {
      --standard_ex
      "ex__luoshen", "ex__guanxing",
      --shzl
      "yinghun",
      --yj
      "nos__miji", "ty_ex__zhenjun", "ty_ex__qianxi", "fumian",
      --sp
      "shenzhi",
      --OL
      "xunzhi", "fujian", "ol__tongdu", "yongzu", "qin__zhangzheng",
      --tenyear
      "fuxue", "miyi", "cansi", "fensi", "huizhi", "silun", "jincui", "langxi", "shunshi", "mouni", "ty__huoshui", "xianwei",
      "yingyu", "dingji", "zhangrong", "fazhu", "wanglu", "hanying", "yanzhengn",
      --mobile
      "yingjian", "liezhi", "mobile__diaodu", "mou__luoshen",
      --overseas
      "os__qingkou", "os__zhiming", "os__tanfeng", "os_xing__zhilue", "os__shengxi", "os__fenming", "os__liexi",
      --jsrg
      "chaozheng", "jizhaoq", "zhuhuanh", "xuanhua", "guyin", "guitu", "qingzi", "js__niluan", "yaoyan", "js__zhimeng",
      --offline
      "rom__zhenglian", "chaojue",
      --qsgs
      --"qyt__dongcha",
      --sanguokill
      "sk__diaodu", "sk__huituo", "sk__caiyu", "sk_le__luoshen", "sk__tiance", "sk__wengua",
    },
    ["phase_finish"] = {
      --standard_ex
      "biyue", "ex__biyue",
      --shzl
      "jushou", "ol_ex__jushou", "zhengu", "zuilun", "meihun",
      --yj
      "ty_ex__zhenjun", "m_ex__jieyue", "nos__miji", "miji", "ty_ex__zishou", "ty_ex__jingce", "juece", "ty_ex__zhiyan",
      "os_ex__bingyi", "daiyan", "huimin",
      "tw__liancai",
      --sp
      "mozhi", "fk__yuanhu", "bifa", "kuiwei", "kunfen",
      --OL
      "ty__tunjiang", "kuanshi", "fujian", "lanjiang", "zhangjiq", "chenshuo", "jieli", "shenfu", "lizhan", 
      --tenyear
      "sp__youdi", "jue", "pijing", "zhuihuan", "nuanhui", "shijiz", "zhenxing", "guanyue", "ty__jieying", "yizhengc", "nifu",
      "ty__qinqing", "suizheng", "ld__shengxi", "haoyi", "sangu", "linghui",
      --mobile
      "chengzhao", "shangjian", "mobile__guixiu", "tianyin", "mou__jieyue", "mou__shipo",
      --overseas
      "os__fenwu", "os__zhiqu", "os__xingluan", "os__qiaosih", "os__juchen", "os__xingbu",
      --jsrg
      "zhaobing", "jizhaoq", "js__cangchu", "js__chuanxin", "js__pianchong",
      --mini
      "mini_zhuixi", "mini_lvyuan",
      --offline
      "shude",
      --qsgs
      "qyt__guixin", "qyt__hujia", "qyt__gongmou", "qw__longluo",
      --sanguokill
      "sk__zuilun", "sk__diancai", "sk__yinyuan", "sk__kuizhu", "sk__qinqing", "sk__chenyu", "sk__huoshui",
    },
    ["phase_play"] = {
      --standard_ex
      "qingnang", "lijian", "hs__kurou",
      "ex__rende", "ex__yijue", "jijie", "ex__zhiheng", "ex__fanjian", "ex__guose", "ex__jieyin", "ex__chuli",
      --shzl
      "ol_ex__qiangxi", "quhu", "tianyi", "ol_ex__luanji", "ol_ex__dimeng", "ol_ex__tiaoxin", "feijun", "jueyan",
      "os__gongxin", "poxi", "ol_ex__changbiao",
      --yj
      "ty_ex__sanyao", "nos__jujian", "ty_ex__jianyan", "m_ex__ganlu", "m_ex__xianzhen", "ty_ex__mingce", "qice", "m_ex__anxu",
      "ty_ex__gongqi", "junxing", "m_ex__junxing", "m_ex__mieji", "mingjian", "ty_ex__anguo", "ty_ex__wurong", "ty_ex__huaiyi",
      "m_ex__yanzhu", "duliang", "zhige",
      "tw__huzhu", "tw__rangyi",
      --sp
      "os__yuanhu", "xueji", "ol__xuehen", "mizhao", "ol__zhoufu", "qiangwu", "ol__fenxun", "xiemu", "ty_ex__quji", "dahe",
      "tanhu",
      --OL
      "ziyuan", "ty__lianzhu", "shanxi", "ty__lianji", "jianji", "shoufu", "guanxu", "liehou", "chongxin", "shengong",
      "qingyix", "xiaosi", "xianbi", "leijie", "yanru", "chanshuang", "shandao", "yichengl", "zuolian", "jinlan", "hunjiang",
      "weimian", "shidu", "choufa", "yanxi", "xuanbei", "yushen", "bolong", "fuxun", "lilun", "yuanlue",
      "qin__bianfa", "qin__qihuo", "qin__youmie",
      --tenyear
      "guolun", "ty_ex__jixu", "kuiji", "jiuxianc", "changqu", "jianguo", "zhuren", "busuan", "xiangmian", "daoshu", "ty__jianji",
      "wencan", "jianzheng", "mansi", "caizhuang", "huahuo", "xinyou", "huiji", "zunwei", "jichun", "qiongying", "tanbei",
      "ty__xiongsuan", "lueming", "tunan", "yanjiao", "ty__songshu", "os__mouzhu", "libang", "nuchen", "ty__wuyuan",
      "huoqi", "xianshou", "minsi", "xuezhao", "ty__qingcheng", "channi", "ty__kuangfu", "qingtan", "jinhui", "cuijian",
      "ty__jianshu", "yingshui", "zigu", "ty__beini", "midu", "qiangzhiz", "ty__fenglue", "boyan", "weimeng", "chiying", "luecheng",
      "kuizhen", "sirui", "liangyan", "wuwei", "kuangzhan", "tongwei", "weiwu", "ol__zhongjian", "ty__qimei", "xuzhi", "beiyu",
      "bianzhuang", "shuangbi", "lisao", "zhongyanz",
      --mobile
      "pingcai", "qiaosi", "zhengjing", "zhilve", "guli", "huiyao", "mobile__yufeng", "beizhu", "poxiang", "zhujian", "duansuo",
      "yizheng", "hannan", "mobile__daoshu", "wisdom__qiai", "shameng", "jianzhan", "ofl__huishi", "mobile__yinju", "nos__cunsi",
      "luanchou", "dingzhou", "shanxie", "zundi", "mobile__shangyi", "yangjie",
      "mou__jushou", "mou__xianzhen", "mou__lijian", "mou__huoji", "mou__quhu", "mou__luanji", "mou__duanliang",
      --overseas
      "os__zhuidu", "os__jimeng", "os__beini", "os__mutao", "os__yuejian", "os__bingde", "os__waishi", "os__daoji", "os__zhanyi",
      "os__juexing", "os__muyue", "os__weipo", "os__shangyi", "os__xuechang", "os__danlie",
      --jsrg
      "pingtao", "js__lianzhu", "shelun", "duxing", "jinmie", "lunshi", "xushiz", "yangming", "shili", "chushi", "js__jinfa",
      "zhuni", "daoren", "saojian", "yansha", "xiangjia",
      --mini
      "mini_xiangzhi", "mini_tongxin", "mini_yanshi", "mini_delu", "mini_zhujiu", "mini_zunbei", "mini_jifeng",
      --offline
      "miaojian", "chaos__lulue", "sgsh__daoshu", "ofl__jinfa", "ofl__zhanyan", "daohe", "zhiyiz", "xuepin", "ofl__shameng", "duyi",
      "mixin", "fuluan",
      --qsgs
      "qyt__jueji", "qyt__guihan", "qw__houyuan",
      --sanguokill
      "sk__hechun", "sk__choujue", "sk__limu", "sk__jiaozhao", "sk__wurong", "sk__taoxi", "sk__guiyuan", "sk__shajue", "sk__yanlie",
      "sk_le__jieyin", "sk__zhengnan",
    },
    ["damaged"] = {
      --standard_ex
      "ex__jianxiong", "ex__yiji", "ex__fankui", "ex__ganglie", "ty__wangxi",
      --shzl
      "ol_ex__jieming", "fangzhu", "ol_ex__beige", "guixin",
      --yj
      "os_ex__enyuan", "zhichi", "ty_ex__zhiyu", "ty_ex__chengxiang", "yuce", "m_ex__duodao", "ty_ex__shibei", "huituo", "qingxian",
      "ty_ex__yaoming",
      --sp
      "ty__jilei", --"fenyong",
      --OL
      "ty__benyu", "chouce", "yashi", "dingcuo", "liejie", "chuanwu", "shilu", "xibing", "zhongyun", "xieshu", "huanghan",
      --tenyear
      "weilu", "ty__baobian", "zhantao", "peiqi", "fumou", "xiace", "qianlong", "yuqi", "silun", "zhenxing", "bihuo",
      "shunshi", "lundao", "jijing", "yachai", "xieshou", "yijia", "jini", "wanggui", "kangli", "qiusuo",
      --mobile
      "rangjie", "jiebing", "xunde", "yiyongw", "difei", "xianchou",
      --overseas
      "os__yangshi", "os__liechi", "os__yimou", "os__fupan", "os__miaolue",
      --jsrg
      "js__rangjie", "dingce", "js__fengxiang", "jueyin",
      --offline
      "langgu",
      --qsgs
      "qyt__guixin", "qyt__chengxiang", "qyt__toudu", "qw__tanlan",
      --sanguokill
      "sk__fulu", "sk__danxin", "sk__xingshuai", "sk__kunfen", "sk__chenyu", "sk__jiexin",
    },
  }
  return table.filter(list[event] or {}, function (skill_name)
    return Fk.skills[skill_name] and not player:hasSkill(skill_name, true)
  end)
end
local sk__yaozhi = fk.CreateActiveSkill{
  name = "sk__yaozhi",
  prompt = "#sk__yaozhi",
  card_num = 0,
  target_num = 0,
  can_use = function(self, player)
    return player:getMark("sk__yaozhi_used-phase") == 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:setPlayerMark(player, "sk__yaozhi_used-phase", 1)
    player:drawCards(1, self.name)
    if player.dead then return end
    local skills = getYaozhiSkills(player, "phase_play")
    if #skills == 0 then return end
    local skill_name = room:askForChoice(player, table.random(skills, 3), self.name, "#sk__yaozhi-choice", true)
    local phase_event = room.logic:getCurrentEvent():findParent(GameEvent.Phase)
    if phase_event ~= nil then
      room:handleAddLoseSkills(player, skill_name, nil, true, false)
      local mark = player:getTableMark("sk__yaozhi")
      table.insertIfNeed(mark, skill_name)
      room:setPlayerMark(player, "sk__yaozhi", mark)
      if not Fk.skills[skill_name]:isInstanceOf(ViewAsSkill) then
        room:askForUseActiveSkill(player, skill_name, "#sk__yaozhi-active:::"..skill_name, true)
        room:handleAddLoseSkills(player, "-"..skill_name, nil, true, false)
      end
      phase_event:addCleaner(function()
        room:handleAddLoseSkills(player, "-"..skill_name, nil, true, false)
      end)
    end
  end,
}
local sk__yaozhi_trigger = fk.CreateTriggerSkill{
  name = "#sk__yaozhi_trigger",
  mute = true,
  main_skill = sk__yaozhi,
  events = {fk.Damaged, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(sk__yaozhi) then
      if event == fk.Damaged then
        return true
      elseif event == fk.EventPhaseStart then
        return player.phase == Player.Start or player.phase == Player.Finish
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("sk__yaozhi")
    room:notifySkillInvoked(player, "sk__yaozhi", "special")
    player:drawCards(1, "sk__yaozhi")
    if player.dead then return end
    local skills = {}
    if event == fk.Damaged then
      skills = getYaozhiSkills(player, "damaged")
    else
      if player.phase == Player.Start then
        skills = getYaozhiSkills(player, "phase_start")
      elseif player.phase == Player.Finish then
        skills = getYaozhiSkills(player, "phase_finish")
      end
    end
    if #skills == 0 then return end
    local skill_name = room:askForChoice(player, table.random(skills, 3), "sk__yaozhi", "#sk__yaozhi-choice", true)
    local skill = Fk.skills[skill_name]
    if skill == nil then return end
    room:handleAddLoseSkills(player, skill_name, nil, true, false)
    local mark = player:getTableMark("sk__yaozhi")
    table.insertIfNeed(mark, skill_name)
    room:setPlayerMark(player, "sk__yaozhi", mark)
    if skill:triggerable(event, target, player, data) then
      skill:trigger(event, target, player, data)
    end
    room:handleAddLoseSkills(player, "-"..skill_name, nil, true, false)
  end,
}
local sk__xingyun = fk.CreateTriggerSkill{
  name = "sk__xingyun",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:changeMaxHp(player, -1)
    if player.dead then return end
    local skills = player:getTableMark("sk__yaozhi")
    skills = table.filter(skills, function (s)
      return not player:hasSkill(s, true)
    end)
    if #skills == 0 then return end
    local result = room:askForCustomDialog(player, self.name,
      "packages/utility/qml/ChooseSkillBox.qml", {
      skills, 1, 1, "#sk__xingyun-choice"
    })
    local skill = ""
    if result == "" then
      skill = table.random(choices)
    end
    local choice = json.decode(result)
    if #choice > 0 then
      skill = choice[1]
    else
      skill = table.random(choices)
    end
    room:handleAddLoseSkills(player, skill, nil, true, false)
  end,
}
sk__yaozhi:addRelatedSkill(sk__yaozhi_trigger)
sp_godzhugeliang:addSkill(sk__yaozhi)
sp_godzhugeliang:addSkill(sk__xingyun)
Fk:loadTranslationTable{
  ["sk_sp__godzhugeliang"] = "神诸葛亮",
  ["#sk_sp__godzhugeliang"] = "",

  ["sk__yaozhi"] = "妖智",
  [":sk__yaozhi"] = "准备阶段/结束阶段/出牌阶段限一次/当你受到伤害后，你可以摸一张牌，然后从随机三个能在此时机发动的技能中选择一个，获得该技能"..
  "直到对应时机结束。",
  ["sk__xingyun"] = "星陨",
  [":sk__xingyun"] = "锁定技，回合结束时，你减1点体力上限，然后获得因〖妖智〗选择过的一个技能。",
  ["#sk__yaozhi_trigger"] = "妖智",
  ["#sk__yaozhi"] = "妖智：从三个“出牌阶段限一次”技能中选择一个发动",
  ["#sk__yaozhi-active"] = "发动“%arg”",
  ["#sk__yaozhi-choice"] = "妖智：选择要学习的技能",
  ["#sk__xingyun-choice"] = "星陨：选择获得的技能",

  ["$sk__yaozhi1"] = "星辰之力，助我灭敌！",
  ["$sk__yaozhi2"] = "世间计谋，尽在掌控。",
  ["$sk__xingyun1"] = "七星不灭，法力不竭！",
  ["$sk__xingyun2"] = "斗转星移，七星借命！",
  ["~sk_sp__godzhugeliang"] = "七星灯灭，魂归九州。",
}

local godmachao = General(extension, "sk__godmachao", "god", 4)
local sk__qianji = fk.CreateViewAsSkill{
  name = "sk__qianji",
  anim_type = "offensive",
  prompt = "#sk__qianji",
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    local c = Fk:cloneCard("slash")
    c.skillName = self.name
    return c
  end,
  before_use = function(self, player, use)
    use.extraUse = true
    player.room:removePlayerMark(player, "@sk__qianji", 1)
  end,
  enabled_at_play = function(self, player)
    return player:getMark("@sk__qianji") > 0 and player.phase == Player.Play
  end,
  enabled_at_response = Util.FalseFunc,
}
local sk__qianji_trigger = fk.CreateTriggerSkill{
  name = "#sk__qianji_trigger",
  mute = true,
  main_skill = sk__qianji,
  events = {fk.GameStart, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianji) then
      if event == fk.GameStart then
        return true
      else
        for _, move in ipairs(data) do
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerEquip and (Fk:getCardById(info.cardId).sub_type == Card.SubtypeDefensiveRide or
              Fk:getCardById(info.cardId).sub_type == Card.SubtypeOffensiveRide) then
              return true
            end
          end
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("sk__qianji")
    if event == fk.GameStart then
      room:notifySkillInvoked(player, "sk__qianji", "drawcard")
      local cards = table.filter(room.draw_pile, function(id)
        local card = Fk:getCardById(id)
        return card.sub_type == Card.SubtypeDefensiveRide and player:canUse(card) and not player:prohibitUse(card)
      end)
      if #cards > 0 then
        room:useCard{
          from = player.id,
          card = Fk:getCardById(table.random(cards)),
        }
      end
      if player.dead then return end
      cards = table.filter(room.draw_pile, function(id)
        local card = Fk:getCardById(id)
        return card.sub_type == Card.SubtypeOffensiveRide and player:canUse(card) and not player:prohibitUse(card)
      end)
      if #cards > 0 then
        room:useCard{
          from = player.id,
          card = Fk:getCardById(table.random(cards)),
        }
      end
    else
      room:notifySkillInvoked(player, "sk__qianji", "special")
      room:addPlayerMark(player, "@sk__qianji", 2)
    end
  end,
}
local sk__qianji_targetmod = fk.CreateTargetModSkill{
  name = "#sk__qianji_targetmod",
  bypass_times = function(self, player, skill, scope, card, to)
    return table.contains(card.skillNames, "sk__qianji")
  end,
  bypass_distances =  function(self, player, skill, card, to)
    return table.contains(card.skillNames, "sk__qianji")
  end,
}
local sk__juechen = fk.CreateTriggerSkill{
  name = "sk__juechen",
  anim_type = "offensive",
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    return target and target == player and player:hasSkill(self) and data.to ~= player and not data.to.dead and
      data.card and data.card.trueName == "slash"
  end,
  on_cost = function(self, event, target, player, data)
    local choice = player.room:askForChoice(player, {"sk__juechen1::"..data.to.id..":"..data.damage,
      "sk__juechen2::"..data.to.id, "Cancel"}, self.name, "#sk__juechen-invoke::"..data.to.id)
    if choice ~= "Cancel" then
      self.cost_data = choice[12]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data == "1" then
      room:loseHp(data.to, data.damage, self.name)
    else
      room:changeMaxHp(data.to, -1)
    end
    return true
  end,
}
sk__qianji:addRelatedSkill(sk__qianji_trigger)
sk__qianji:addRelatedSkill(sk__qianji_targetmod)
godmachao:addSkill(sk__qianji)
godmachao:addSkill(sk__juechen)
Fk:loadTranslationTable{
  ["sk__godmachao"] = "神马超",
  ["#sk__godmachao"] = "神威天将军",

  ["sk__qianji"] = "千骑",
  [":sk__qianji"] = "游戏开始时，你从牌堆随机使用一张防御坐骑牌和一张进攻坐骑牌。当一名角色失去装备区内的坐骑牌后，你获得2枚“千骑”标记。"..
  "出牌阶段，你可以弃置一枚“千骑”标记，视为使用一张无距离次数限制的【杀】。",
  ["sk__juechen"] = "绝尘",
  [":sk__juechen"] = "当你使用【杀】对其他角色造成伤害时，你可以防止此伤害，改为令其失去等量的体力或减1点体力上限。",
  ["#sk__qianji"] = "千骑：你可以弃置一枚“千骑”标记，视为使用一张无距离次数限制的【杀】",
  ["@sk__qianji"] = "千骑",
  ["#sk__juechen-invoke"] = "绝尘：是否防止对 %dest 造成的伤害，改为令其失去体力或减1点体力上限？",
  ["sk__juechen1"] = "%dest失去%arg点体力",
  ["sk__juechen2"] = "%dest减1点体力上限",

  ["$sk__qianji1"] = "千军万马，随我破阵杀敌！",
  ["$sk__qianji2"] = "得此良驹，我军无人可挡！",
  ["$sk__qianji3"] = "这就是，一骑当千的力量！",
  ["$sk__qianji4"] = "你被包围了，还不束手就擒？",
  ["$sk__juechen1"] = "奔逸绝尘，袭敌无影！",
  ["$sk__juechen2"] = "哈哈哈哈哈！太慢了！",
  ["~sk__godmachao"] = "（马蹄声）",
}

local sp_godlvbu = General(extension, "sk_sp__godlvbu", "god", 2)
local sk__luocha = fk.CreateTriggerSkill{
  name = "sk__luocha",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.GameStart, fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif event == fk.EnterDying then
        return target ~= player
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 1
    if event == fk.GameStart then
      n = 3
    elseif event == fk.EnterDying then
      player:drawCards(2, self.name)
    end
    if player.dead then return end
    local skills = {}
    for _, general in ipairs(Fk:getAllGenerals()) do
      for _, skill in ipairs(general:getSkillNameList()) do
        if string.find(Fk:translate(":"..skill, "zh_CN"), "【杀】") and not player:hasSkill(skill, true) then
          table.insertIfNeed(skills, skill)
        end
      end
    end
    if #skills > 0 then
      skills = table.random(skills, n)
      room:handleAddLoseSkills(player, skills, nil, true, false)
    end
  end,
}
local sk__shajue = fk.CreateActiveSkill{
  name = "sk__shajue",
  anim_type = "offensive",
  prompt = "#sk__shajue",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and to_select ~= player.id
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local cards = table.simpleClone(player:getCardIds("h"))
    room:loseHp(player, 1, self.name)
    local slash_names = {}
    for _, card in ipairs(Fk.cards) do
      if not table.contains(room.disabled_packs, card.package.name) and not card.is_derived and card.trueName == "slash" then
        table.insertIfNeed(slash_names, card.name)
      end
    end
    math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 6)))
    while not player.dead do
      cards = table.filter(cards, function(id)
        return table.contains(player:getCardIds("h"), id)
      end)
      if #cards == 0 or target.dead then return end
      room:delay(800)
      if not room:useVirtualCard(table.random(slash_names), table.random(cards, 1), player, target, self.name, true) then
        break
      end
    end
  end,
}
local sk__shajue_trigger = fk.CreateTriggerSkill{
  name = "#sk__shajue_trigger",

  refresh_events = {fk.TargetSpecified},
  can_refresh = function(self, event, target, player, data)
    return target == player and table.contains(data.card.skillNames, "sk__shajue")
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.to)
    local use_event = room.logic:getCurrentEvent():findParent(GameEvent.UseCard, true)
    if use_event == nil then return end
    room:addPlayerMark(to, fk.MarkArmorNullified)
    use_event:addCleaner(function()
      room:removePlayerMark(to, fk.MarkArmorNullified)
    end)
  end,
}
local sk__guiqu = fk.CreateViewAsSkill{
  name = "sk__guiqu",
  anim_type = "support",
  frequency = Skill.Compulsory,  --已经不想吐槽锁定转化技了
  pattern = "peach",
  prompt = "#sk__guiqu",
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    local card = Fk:cloneCard("peach")
    card.skillName = self.name
    return card
  end,
  before_use = function (self, player, use)
    local room = player.room
    local skills = {}
    for _, s in ipairs(player.player_skills) do
      if s:isPlayerSkill(player) and s.visible then
        table.insert(skills, s.name)
      end
    end
    local result = room:askForCustomDialog(player, self.name,
      "packages/utility/qml/ChooseSkillBox.qml", {
      skills, 1, 1, "#sk__guiqu-choice"
    })
    local skill = ""
    if result == "" then
      skill = table.random(skills)
    end
    local choice = json.decode(result)
    if #choice > 0 then
      skill = choice[1]
    else
      skill = table.random(skills)
    end
    room:handleAddLoseSkills(player, "-"..skill, nil, true, false)
  end,
  enabled_at_play = Util.FalseFunc,
  enabled_at_response = function(self, player, response)
    return not response and player.dying
  end,
}
local sk__guiqu_maxcards = fk.CreateMaxCardsSkill{
  name = "#sk__guiqu_maxcards",
  frequency = Skill.Compulsory,
  main_skill = sk__guiqu,
  fixed_func = function(self, player)
    if player:hasSkill(sk__guiqu) then
      return #table.filter(player.player_skills, function (s)
        return s:isPlayerSkill(player) and s.visible
      end)
    end
  end,
}
sk__shajue:addRelatedSkill(sk__shajue_trigger)
sk__guiqu:addRelatedSkill(sk__guiqu_maxcards)
sp_godlvbu:addSkill(sk__luocha)
sp_godlvbu:addSkill(sk__shajue)
sp_godlvbu:addSkill(sk__guiqu)
Fk:loadTranslationTable{
  ["sk_sp__godlvbu"] = "神吕布",
  ["#sk_sp__godlvbu"] = "罗刹天",

  ["sk__luocha"] = "罗刹",
  [":sk__luocha"] = "锁定技，游戏开始时，你随机获得三个描述中包含【杀】的技能；当其他角色进入濒死状态时，你摸两张牌，然后随机获得一个"..
  "描述中包含【杀】的技能。",
  ["sk__shajue"] = "杀绝",
  [":sk__shajue"] = "出牌阶段限一次，你可以失去1点体力并选择一名其他角色，将你当前手牌中的每一张牌当随机属性且无视防具的【杀】对其使用。",
  ["sk__guiqu"] = "鬼躯",
  [":sk__guiqu"] = "锁定技，你的手牌上限为你的技能数。当你处于濒死状态时，你可以失去一个技能，视为使用【桃】。",
  ["#sk__shajue"] = "杀绝：失去1点体力，将你的每一张手牌当随机属性且无视防具的【杀】对一名角色使用！",
  ["#sk__guiqu"] = "鬼躯：你可以失去一个技能，视为使用【桃】",
  ["#sk__guiqu-choice"] = "鬼躯：选择失去的技能",

  ["$sk__luocha1"] = "超越，死亡的恐惧！",
  ["$sk__luocha2"] = "我，即是不灭！",
  ["$sk__shajue1"] = "不死不休！",
  ["$sk__shajue2"] = "这，就是地狱！",
  ["$sk__guiqu1"] = "天雷，吾亦不惧！",
  ["$sk__guiqu2"] = "鬼神之躯，怎能被凡人摧毁！",
  ["~sk_sp__godlvbu"] = "不……我是不朽的！",
}

local godzhenji = General(extension, "sk__godzhenji", "god", 3, 3, General.Female)
local sk__shenfu = fk.CreateTriggerSkill{
  name = "sk__shenfu",
  anim_type = "drawcard",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:getHandcardNum() < 4 then
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              return true
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark("@sk__shenfu")
    for _, move in ipairs(data) do
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand then
            if #move.moveInfo == 1 then
              local suit = Fk:getCardById(info.cardId):getSuitString(true)
              if suit == "log_nosuit" then
                table.insert(mark, "×")
              else
                table.insert(mark, suit)
              end
            else
              table.insert(mark, "×")
              break
            end
          end
        end
      end
    end
    if #mark > 4 then
      local n = #mark - 4
      for i = 1, n, 1 do
        table.remove(mark, 1)
      end
    end
    room:setPlayerMark(player, "@sk__shenfu", mark)
    player:drawCards(4 - player:getHandcardNum(), self.name)
    if not table.contains(mark, "×") and #mark == 4 and
      (mark[1] ~= mark[2] and mark[1] ~= mark[3] and mark[1] ~= mark[4] and
      mark[2] ~= mark[3] and mark[2] ~= mark[4] and mark[3] ~= mark[4]) then
      local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
        "#sk__shenfu-choose", self.name, true)
      if #to > 0 then
        room:damage({
          from = player,
          to = room:getPlayerById(to[1]),
          damage = 1,
          damageType = fk.ThunderDamage,
          skillName = self.name,
        })
      end
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "@sk__shenfu", 0)
  end,
}
godzhenji:addSkill(sk__shenfu)
Fk:loadTranslationTable{
  ["sk__godzhenji"] = "神甄姬",
  ["#sk__godzhenji"] = "洛川的女神",

  ["sk__shenfu"] = "神赋",
  [":sk__shenfu"] = "当你失去手牌后，你可以将手牌摸至四张，然后若你最近四次发动〖神赋〗的失去牌事件中均只失去一张牌且花色各不相同，你可以"..
  "对一名角色造成1点雷电伤害。",
  ["@sk__shenfu"] = "神赋",
  ["#sk__shenfu-choose"] = "神赋：你可以对一名角色造成1点雷电伤害",

  ["$sk__shenfu1"] = "动无常则，若危若安。",
  ["$sk__shenfu2"] = "进止难期，若往若还。",
  ["$sk__shenfu3"] = "转眄流精，光润玉颜。",
  ["~sk__godzhenji"] = "今夕，何夕……",
}

local sp_godzhangjiao = General(extension, "sk_sp__godzhangjiao", "god", 3)
local sk__yinyang = fk.CreateTriggerSkill{
  name = "sk__yinyang",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.HpChanged, fk.MaxHpChanged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      return (player.hp > player:getLostHp() and not player:hasSkill("sk__jiyang", true)) or
        (player.hp < player:getLostHp() and not player:hasSkill("sk__jiyin", true)) or
        (player.hp == player:getLostHp() and not player:hasSkill("sk__xiangsheng", true))
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player.hp > player:getLostHp() then
      room:handleAddLoseSkills(player, "sk__jiyang|-sk__jiyin|-sk__xiangsheng", nil, true, false)
    elseif player.hp < player:getLostHp() then
      room:handleAddLoseSkills(player, "sk__jiyin|-sk__jiyang|-sk__xiangsheng", nil, true, false)
    elseif player.hp == player:getLostHp() then
      room:handleAddLoseSkills(player, "sk__xiangsheng|-sk__jiyang|-sk__jiyin", nil, true, false)
    end
  end,

  refresh_events = {fk.EventAcquireSkill, fk.EventLoseSkill},
  can_refresh = function (self, event, target, player, data)
    return target == player and data == self
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventAcquireSkill then
      if player.hp > player:getLostHp() then
        room:handleAddLoseSkills(player, "sk__jiyang|-sk__jiyin|-sk__xiangsheng", nil, true, false)
      elseif player.hp < player:getLostHp() then
        room:handleAddLoseSkills(player, "sk__jiyin|-sk__jiyang|-sk__xiangsheng", nil, true, false)
      elseif player.hp == player:getLostHp() then
        room:handleAddLoseSkills(player, "sk__xiangsheng|-sk__jiyang|-sk__jiyin", nil, true, false)
      end
    elseif event == fk.EventLoseSkill then
      room:handleAddLoseSkills(player, "-sk__jiyang|-sk__jiyin|-sk__xiangsheng", nil, true, false)
    end
  end,
}
local sk__jiyang = fk.CreateTriggerSkill{
  name = "sk__jiyang",
  anim_type = "support",
  frequency = Skill.Compulsory,
  events = {fk.EventAcquireSkill, fk.EventLoseSkill, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventAcquireSkill or event == fk.EventLoseSkill then
      return target == player and data == self and not player.dead
    else
      if player:hasSkill(self) and player:getMark("@sk__jiyang") > 0 then
        for _, move in ipairs(data) do
          if move.from == player.id then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
                Fk:getCardById(info.cardId).color == Card.Red then
                return true
              end
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventAcquireSkill then
      room:addPlayerMark(player, "@sk__jiyang", 3)
    elseif event == fk.EventLoseSkill then
      local n = player:getMark("@sk__jiyang")
      room:setPlayerMark(player, "@sk__jiyang", 0)
      if n > 0 then
        local cards = room:getCardsFromPileByRule(".|.|heart,diamond", n, "drawPile")
        if #cards > 0 then
          room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonDraw, self.name, nil, false, player.id)
        end
      end
    else
      local n = 0
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              Fk:getCardById(info.cardId).color == Card.Red then
                n = n + 1
            end
          end
        end
      end
      for i = 1, n, 1 do
        if player.dead or player:getMark("@sk__jiyang") == 0 then return end
        local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
          "#sk__jiyang-choose", self.name, true)
        if #to > 0 then
          room:removePlayerMark(player, "@sk__jiyang", 1)
          to = room:getPlayerById(to[1])
          if to:isWounded() then
            room:recover({
              who = to,
              num = 1,
              recoverBy = player,
              skillName = self.name,
            })
          else
            room:changeMaxHp(to, 1)
          end
        else
          return
        end
      end
    end
  end,
}
local sk__jiyin = fk.CreateTriggerSkill{
  name = "sk__jiyin",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.EventAcquireSkill, fk.EventLoseSkill, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventAcquireSkill or event == fk.EventLoseSkill then
      return target == player and data == self and not player.dead
    else
      if player:hasSkill(self) and player:getMark("@sk__jiyin") > 0 then
        for _, move in ipairs(data) do
          if move.from == player.id then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
                Fk:getCardById(info.cardId).color == Card.Black then
                return true
              end
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventAcquireSkill then
      room:addPlayerMark(player, "@sk__jiyin", 3)
    elseif event == fk.EventLoseSkill then
      local n = player:getMark("@sk__jiyin")
      room:setPlayerMark(player, "@sk__jiyin", 0)
      if n > 0 then
        local cards = room:getCardsFromPileByRule(".|.|spade,club", n, "drawPile")
        if #cards > 0 then
          room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonDraw, self.name, nil, false, player.id)
        end
      end
    else
      local n = 0
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              Fk:getCardById(info.cardId).color == Card.Black then
                n = n + 1
            end
          end
        end
      end
      for i = 1, n, 1 do
        if player.dead or player:getMark("@sk__jiyin") == 0 then return end
        local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
          "#sk__jiyin-choose", self.name, true)
        if #to > 0 then
          room:removePlayerMark(player, "@sk__jiyin", 1)
          to = room:getPlayerById(to[1])
          if to:isWounded() then
            room:changeMaxHp(to, -1)
          else
            room:damage{
              from = player,
              to = to,
              damage = 1,
              damageType = fk.ThunderDamage,
              skillName = self.name,
            }
          end
        else
          return
        end
      end
    end
  end,
}
local sk__xiangsheng = fk.CreateTriggerSkill{
  name = "sk__xiangsheng",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.EventAcquireSkill, fk.EventLoseSkill, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if event == fk.EventAcquireSkill or event == fk.EventLoseSkill then
      return target == player and data == self and not player.dead
    else
      if player:hasSkill(self) and player:getMark("@sk__xiangsheng") > 0 then
        for _, move in ipairs(data) do
          if move.from == player.id then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) then
                return true
              end
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventAcquireSkill then
      room:addPlayerMark(player, "@sk__xiangsheng", 6)
    elseif event == fk.EventLoseSkill then
      local n = player:getMark("@sk__xiangsheng")
      room:setPlayerMark(player, "@sk__xiangsheng", 0)
      if n > 0 then
        player:drawCards(n, self.name)
      end
    else
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) then
              if player.dead or player:getMark("@sk__xiangsheng") == 0 then return end
              local prompt = ""
              if Fk:getCardById(info.cardId).color == Card.Black then
                prompt = "#sk__xiangsheng1-invoke"
              elseif Fk:getCardById(info.cardId).color == Card.Red then
                prompt = "#sk__xiangsheng2-invoke"
              end
              if prompt ~= "" and room:askForSkillInvoke(player, self.name, nil, prompt) then
                room:removePlayerMark(player, "@sk__xiangsheng", 1)
                local pattern = ".|.|spade,club"
                if prompt == "#sk__xiangsheng1-invoke" then
                  pattern = ".|.|heart,diamond"
                end
                local cards = room:getCardsFromPileByRule(pattern, 1, "drawPile")
                if #cards > 0 then
                  room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonDraw, self.name, nil, false, player.id)
                end
              end
            end
          end
        end
      end
    end
  end,
}
local sk__dingming = fk.CreateTriggerSkill{
  name = "sk__dingming",
  anim_type = "masochism",
  events = {fk.TurnStart, fk.Damaged, fk.Damage},
  can_trigger = function(self, event, target, player, data)
    if target and target == player and player:hasSkill(self) then
      if event == fk.TurnStart then
        return true
      elseif event == fk.Damaged then
        return data.from and data.from ~= player
      elseif event == fk.Damage then
        return data.to ~= player and not data.to.dead
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.TurnStart or event == fk.Damaged then
      self.cost_data = player
    else
      self.cost_data = data.to
    end
    return player.room:askForSkillInvoke(player, self.name, nil, "#sk__dingming-invoke::"..self.cost_data.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = self.cost_data
    room:doIndicate(player.id, {to.id})
    local n = math.max(0, to.hp) - math.min(to.maxHp, to:getLostHp())
    if n > 0 then
      room:loseHp(to, n, self.name)
    elseif n < 0 and to:isWounded() then
      room:recover({
        who = to,
        num = -n,
        recoverBy = player,
        skillName = self.name,
      })
    end
    if to == player and not player.dead and player.hp > player:getLostHp() then
      room:changeMaxHp(player, -1)
    elseif to ~= player and not player.dead and to.hp < to:getLostHp() then
      room:changeMaxHp(player, -1)
    end
    if not player.dead and n ~= 0 then
      player:drawCards(math.abs(n), self.name)
    end
  end,
}
sp_godzhangjiao:addSkill(sk__yinyang)
sp_godzhangjiao:addSkill(sk__dingming)
sp_godzhangjiao:addRelatedSkill(sk__jiyang)
sp_godzhangjiao:addRelatedSkill(sk__jiyin)
sp_godzhangjiao:addRelatedSkill(sk__xiangsheng)
Fk:loadTranslationTable{
  ["sk_sp__godzhangjiao"] = "神张角",
  ["#sk_sp__godzhangjiao"] = "大道无常",

  ["sk__yinyang"] = "阴阳",
  [":sk__yinyang"] = "锁定技，若你的体力值：大于已损失体力值，你拥有技能〖极阳〗；小于已损失体力值，你拥有技能〖极阴〗；等于已损失体力值，"..
  "你拥有技能〖相生〗。",
  ["sk__dingming"] = "定命",
  [":sk__dingming"] = "回合开始时或当你受到其他角色造成的伤害后，你可以交换体力值与已损失体力值，然后若你的体力值大于已损失体力值，"..
  "你减1点体力上限；当你对其他角色造成伤害后，你可以令其交换体力值与已损失体力值，然后若其体力值小于已损失体力值，你减1点体力上限。"..
  "然后你摸X张牌（X为交换的体力值与已损失体力值之差）。",
  ["sk__jiyang"] = "极阳",
  [":sk__jiyang"] = "锁定技，当你获得此技能后，你获得3枚“阳”标记；当你失去此技能后，你弃置所有“阳”标记，摸等量的红色牌。"..
  "当你失去红色牌后，你可以弃置1枚“阳”标记，令一名角色回复1点体力；若其未受伤，改为加1点体力上限。",
  ["sk__jiyin"] = "极阴",
  [":sk__jiyin"] = "锁定技，当你获得此技能后，你获得3枚“阴”标记；当你失去此技能后，你弃置所有“阴”标记，摸等量的黑色牌。"..
  "当你失去黑色牌后，你可以弃置1枚“阴”标记，对一名角色造成1点雷电伤害；若其已受伤，改为减1点体力上限。",
  ["sk__xiangsheng"] = "相生",
  [":sk__xiangsheng"] = "锁定技，当你获得此技能后，你获得6枚“生”标记；当你失去此技能后，你弃置所有“生”标记，摸等量的牌。"..
  "你失去黑色/红色牌后，你可以弃置1枚“生”标记，摸一张红色/黑色牌。",
  ["#sk__dingming-invoke"] = "定命：是否令 %dest 交换体力值与已损失体力值？",
  ["@sk__jiyang"] = "阳",
  ["#sk__jiyang-choose"] = "极阳：你可以弃置一枚“阳”标记令一名角色回复1点体力，若其未受伤，改为加1点体力上限",
  ["@sk__jiyin"] = "阴",
  ["#sk__jiyin-choose"] = "极阴：你可以弃置一枚“阴”标记对一名角色造成1点雷电伤害，若其已受伤，改为减1点体力上限",
  ["@sk__xiangsheng"] = "生",
  ["#sk__xiangsheng1-invoke"] = "相生：你可以弃置一枚“生”标记，摸一张红色牌",
  ["#sk__xiangsheng2-invoke"] = "相生：你可以弃置一枚“生”标记，摸一张黑色牌",


  ["$sk__yinyang1"] = "世间万物，皆有阴阳之道。",
  ["$sk__yinyang2"] = "亦阴亦阳，道用无穷。",
  ["$sk__dingming1"] = "苍天不负，黄天立命！",
  ["$sk__dingming2"] = "窥晓阴阳，逆天改命！",
  ["$sk__jiyang1"] = "极阳之力，救苍生万民。",
  ["$sk__jiyang2"] = "道亦阳善，平天下乱世。",
  ["$sk__jiyin1"] = "极阴之力，毁灭一切！",
  ["$sk__jiyin2"] = "阴雷诛灭，电纵九天！",
  ["$sk__xiangsheng1"] = "阴阳相生，道法自然。",
  ["$sk__xiangsheng2"] = "周而复始，生生不息。",
  ["~sk_sp__godzhangjiao"] = "为何苍天，还没死……",
}

local godhuanggai = General(extension, "sk__godhuanggai", "god", 6)
local sk__lianti = fk.CreateTriggerSkill{
  name = "sk__lianti",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.EventAcquireSkill, fk.BeforeChainStateChange, fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventAcquireSkill then
        return target == player and data == self and not player.chained
      elseif event == fk.BeforeChainStateChange then
        return target == player and player.chained
      elseif event == fk.Damaged then
        if target ~= player and player.phase ~= Player.NotActive and data.damageType ~= fk.NormalDamage and not target.dead then
          local room = player.room
          local damage_event = room.logic:getCurrentEvent()
          if not damage_event then return end
          local x = 0
          room.logic:getEventsOfScope(GameEvent.ChangeHp, 1, function (e)
            local reason = e.data[3]
            if reason == "damage" then
              local first_damage_event = e:findParent(GameEvent.Damage)
              if first_damage_event then
                local damage = first_damage_event.data[1]
                if damage.damageType ~= fk.NormalDamage and damage.to ~= player then
                  x = first_damage_event.id
                  return true
                end
              end
            end
          end, Player.HistoryTurn)
          return damage_event.id == x
        else
          return target == player and data.damageType ~= fk.NormalDamage
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.EventAcquireSkill then
      player:setChainState(true)
    elseif event == fk.BeforeChainStateChange then
      return true
    elseif event == fk.Damaged then
      local room = player.room
      player:broadcastSkillInvoke(self.name)
      if target ~= player then
        room:notifySkillInvoked(player, self.name, "offensive")
        room:doIndicate(player.id, {target.id})
        room:damage{
          from = player,
          to = target,
          damage = data.damage,
          damageType = data.damageType,
          skillName = self.name,
        }
      else
        room:notifySkillInvoked(player, self.name, "drawcard")
        room:addPlayerMark(player, MarkEnum.AddMaxCards, 1)
        room:addPlayerMark(player, MarkEnum.SkDrawNCards, 1)
        local damage_event = room.logic:getCurrentEvent():findParent(GameEvent.Damage)
        if not damage_event then return end
        local x = 0
        room.logic:getEventsOfScope(GameEvent.ChangeHp, 1, function (e)
          local reason = e.data[3]
          if reason == "damage" then
            local first_damage_event = e:findParent(GameEvent.Damage)
            if first_damage_event then
              local damage = first_damage_event.data[1]
              if damage.damageType ~= fk.NormalDamage and damage.to == player then
                x = first_damage_event.id
                return true
              end
            end
          end
        end, Player.HistoryRound)
        if damage_event.id == x then
          room:changeMaxHp(player, -1)
        end
      end
    end
  end,
}
local sk__yanlie = fk.CreateActiveSkill{
  name = "sk__yanlie",
  anim_type = "offensive",
  min_card_num = 1,
  min_target_num = 1,
  prompt = "#sk__yanlie",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter =function (self, to_select, selected, player)
    return not player:prohibitDiscard(Fk:getCardById(to_select))
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected < #selected_cards and to_select ~= player.id then
      return not player:isProhibited(Fk:currentRoom():getPlayerById(to_select), Fk:cloneCard("iron_chain"))
    end
  end,
  feasible = function(self, selected, selected_cards)
    return #selected == #selected_cards and #selected > 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:throwCard(effect.cards, self.name, player, player)
    room:sortPlayersByAction(effect.tos)
    local card = Fk:cloneCard("iron_chain")
    card.skillName = self.name
    local use = {
      from = player.id,
      tos = table.map(effect.tos, function(id) return { id } end),
      card = card,
      prohibitedCardNames = { "nullification" },
    }
    room:useCard(use)
    if not player.dead then
      local targets = table.map(table.filter(room.alive_players, function (p)
        return p.chained
      end), Util.IdMapper)
      if #targets > 0 then
        local to = room:askForChoosePlayers(player, targets, 1, 1, "#sk__yanlie-damage", self.name, false)
        room:damage {
          from = player,
          to = room:getPlayerById(to[1]),
          damage = 1,
          damageType = fk.FireDamage,
          skillName = self.name,
        }
      end
    end
  end,
}
godhuanggai:addSkill(sk__lianti)
godhuanggai:addSkill(sk__yanlie)
Fk:loadTranslationTable{
  ["sk__godhuanggai"] = "神黄盖",
  ["#sk__godhuanggai"] = "破舰炎天",

  ["sk__lianti"] = "炼体",
  [":sk__lianti"] = "锁定技，你始终处于横置状态。当其他角色于你的回合内第一次受到属性伤害后，你对其造成等量的同属性伤害。当你受到属性伤害后，"..
  "你本局游戏摸牌阶段摸牌数和手牌上限+1，然后若此伤害是你本轮第一次受到属性伤害，你减1点体力上限。",
  ["sk__yanlie"] = "炎烈",
  [":sk__yanlie"] = "出牌阶段限一次，你可以弃置任意张手牌并选择等量的其他角色，视为你对这些角色使用【铁锁连环】（不能被【无懈可击】响应），"..
  "然后你对一名横置的角色造成1点火焰伤害。",

  ["#sk__yanlie"] = "炎烈：弃置任意张手牌，视为对等量的角色使用【铁锁连环】，然后对一名横置角色造成1点火焰伤害",
  ["#sk__yanlie-damage"] = "炎烈：对一名横置角色造成1点火焰伤害",

  ["$sk__lianti1"] = "刀山火海，死亦无惧！",
  ["$sk__lianti2"] = "皮肉之苦，不足挂齿！",
  ["$sk__yanlie1"] = "东风已起，随我冲！！",
  ["$sk__yanlie2"] = "感受这烈火的咆哮吧！",
  ["~sk__godhuanggai"] = "雄心尚在，英雄迟暮啊！",
}

local sp_godzhangliao = General(extension, "sk_sp__godzhangliao", "god", 4)
local sk__fengying = fk.CreateTriggerSkill{
  name = "sk__fengying",
  anim_type = "offensive",
  events = {fk.BeforeDrawCard},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryTurn) < 4
  end,
  on_trigger = function(self, event, target, player, data)
    self.cancel_cost = false
    while data.num > 0 do
      if not player:hasSkill(self) or self.cancel_cost or player:usedSkillTimes(self.name, Player.HistoryTurn) > 3 then return end
      self:doCost(event, target, player, data)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local use = U.askForUseVirtualCard(player.room, player, "thunder__slash", nil, self.name,
      "#sk__fengying-invoke", true, true, true, true, nil, true)
    if use then
      self.cost_data = use
      return true
    end
    self.cancel_cost = true
  end,
  on_use = function(self, event, target, player, data)
    data.num = data.num - 1
    player.room:useCard(self.cost_data)
  end,
}
local sk__zhiti = fk.CreateTriggerSkill{
  name = "sk__zhiti",
  anim_type = "control",
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    if target and target == player and player:hasSkill(self) and data.to ~= player and not data.to.dead then
      local mark = player:getTableMark(self.name)
      mark[string.format("%.0f", data.to.id)] = mark[string.format("%.0f", data.to.id)] or {}
      self.cost_data = mark[string.format("%.0f", data.to.id)]
      return #self.cost_data < 5
    end
  end,
  on_cost = function(self, event, target, player, data)
    local choices, all_choices = {}, {}
    for i = 1, 5, 1 do
      table.insert(all_choices, "sk__zhiti"..i)
      if not table.contains(self.cost_data, i) then
        table.insert(choices, "sk__zhiti"..i)
      end
    end
    table.insert(all_choices, "Cancel")
    table.insert(choices, "Cancel")
    if #choices > 1 then
      local choice = player.room:askForChoice(player, choices, self.name, "#sk__zhiti-invoke::"..data.to.id, false, all_choices)
      if choice ~= "Cancel" then
        self.cost_data = {tonumber(choice[10]), self.cost_data}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark(self.name)
    local n = self.cost_data[1]
    table.insert(self.cost_data[2], n)
    mark[string.format("%.0f", data.to.id)] = self.cost_data[2]
    room:setPlayerMark(player, self.name, mark)
    if n == 1 then
      room:loseHp(data.to, 1, self.name)
      room:changeMaxHp(data.to, -1)
      if not player.dead then
        room:changeMaxHp(player, 1)
        if not player.dead and player:isWounded() then
          room:recover({
            who = player,
            num = 1,
            recoverBy = player,
            skillName = self.name,
          })
        end
      end
    elseif n == 2 then
      room:setPlayerMark(data.to, MarkEnum.SkDrawNCards, data.to:getMark(MarkEnum.SkDrawNCards) - 1)
      room:addPlayerMark(player, MarkEnum.SkDrawNCards, 1)
    elseif n == 3 then
      local skill = ""
      local skills = table.map(table.filter(data.to.player_skills, function(s)
        return s:isPlayerSkill(data.to) and s.visible and not player:hasSkill(s, true)
      end), function(s)
        return s.name
      end)
      if #skills > 0 then
        local result = room:askForCustomDialog(player, self.name,
          "packages/utility/qml/ChooseSkillBox.qml", {
            skills, 1, 1, "#sk__zhiti-choice::"..data.to.id
        })
        local skill = ""
        if result == "" then
          skill = table.random(choices)
        end
        local choice = json.decode(result)
        if #choice > 0 then
          skill = choice[1]
        else
          skill = table.random(choices)
        end
        room:handleAddLoseSkills(data.to, "-"..skill, nil, true, false)
        if not player.dead then
          room:handleAddLoseSkills(player, skill, nil, true, false)
        end
      end
    elseif n == 4 then
      room:setPlayerMark(data.to, "@@sk__zhiti_ban", 1)
    elseif n == 5 then
      data.to:turnOver()
    end
  end,
}
local sk__zhiti_prohibit = fk.CreateProhibitSkill{
  name = "#sk__zhiti_prohibit",
  prohibit_use = function(self, player, card)
    return player:getMark("@@sk__zhiti_ban") > 0 and card and card.type == Card.TypeEquip
  end,
}
sk__zhiti:addRelatedSkill(sk__zhiti_prohibit)
sp_godzhangliao:addSkill(sk__fengying)
sp_godzhangliao:addSkill(sk__zhiti)
Fk:loadTranslationTable{
  ["sk_sp__godzhangliao"] = "神张辽",
  ["#sk_sp__godzhangliao"] = "雁门之刑天",

  ["sk__fengying"] = "锋影",
  [":sk__fengying"] = "每回合限四次，当你摸一张牌前，你可以放弃摸牌，改为视为使用一张无距离限制的雷【杀】。",
  ["sk__zhiti"] = "止啼",
  [":sk__zhiti"] = "当你对其他角色造成伤害时，你可以选择一项，每名角色每项限一次：<br>1.偷取其1点体力和体力上限；<br>"..
  "2.偷取其一张摸牌阶段摸牌数；<br>3.偷取其一个技能；<br>4.令其本局游戏不能使用装备牌；<br>5.令其翻面。",
  ["#sk__fengying-invoke"] = "锋影：是否少摸一张牌，视为使用雷【杀】？",
  ["#sk__zhiti-invoke"] = "止啼：选择对 %dest 执行的一项！",
  ["sk__zhiti1"] = "偷取其1点体力和体力上限",
  ["sk__zhiti2"] = "偷取其一张摸牌阶段摸牌数",
  ["sk__zhiti3"] = "偷取其一个技能",
  ["sk__zhiti4"] = "令其本局游戏不能使用装备牌",
  ["sk__zhiti5"] = "令其翻面",
  ["@@sk__zhiti_ban"] = "禁止使用装备",
  ["#sk__zhiti-choice"] = "止啼：选择偷取 %dest 的技能",

  ["$sk__fengying1"] = "刀锋如影，破敌无形。",
  ["$sk__fengying2"] = "东吴十万，吾亦可夺之锐气！",
  ["$sk__zhiti1"] = "江东小儿，安敢啼哭！",
  ["$sk__zhiti2"] = "吾便是东吴的梦魇！",
  ["~sk_sp__godzhangliao"] = "患病之躯，亦当战死沙场……",
}

local godxuchu = General(extension, "sk__godxuchu", "god", 5)
local sk__huchi = fk.CreateViewAsSkill{
  name = "sk__huchi",
  anim_type = "offensive",
  prompt = "#sk__huchi",
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    local card = Fk:cloneCard("duel")
    card.skillName = self.name
    return card
  end,
  before_use = function(self, player, use)
    use.prohibitedCardNames = {"nullification"}
  end,
  after_use = function(self, player, use)
    local room = player.room
    if not player.dead then
      if use.damageDealt then
        if use.extra_data and use.extra_data.sk__huchi then
          room:setPlayerMark(player, "@@sk__huchi-phase", 1)
        end
        if use.damageDealt[player.id] then
          player:drawCards(3, self.name)
        end
      else
        room:setPlayerMark(player, "@@sk__huchi-phase", 1)
      end
    end
    for _, id in ipairs(TargetGroup:getRealTargets(use.tos)) do
      local to = room:getPlayerById(id)
      if use.damageDealt and use.damageDealt[id] and not to.dead then
        to:drawCards(3, self.name)
      end
    end
  end,
  enabled_at_play = function(self, player)
    return player:getMark("@@sk__huchi-phase") == 0
  end,
}
local sk__huchi_trigger = fk.CreateTriggerSkill{
  name = "#sk__huchi_trigger",

  refresh_events = {fk.EnterDying},
  can_refresh = function(self, event, target, player, data)
    return data.damage and data.damage.card and table.contains(data.damage.card.skillNames, "sk__huchi")
  end,
  on_refresh = function(self, event, target, player, data)
    local e = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
    if e then
      local use = e.data[1]
      use.extra_data = use.extra_data or {}
      use.extra_data.sk__huchi = true
    end
  end,
}
local sk__xiejia = fk.CreateTriggerSkill{
  name = "sk__xiejia",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    return target and target == player and player:hasSkill(self) and data.to ~= player and data.card and
      (data.card.trueName == "slash" or data.card.trueName == "duel") and player.room.logic:damageByCardEffect(true) and
      (#player:getEquipments(Card.SubtypeArmor) == 0 or player:getMark(self.name) > 0)
  end,
  on_use = function(self, event, target, player, data)
    if #player:getEquipments(Card.SubtypeArmor) == 0 then
      data.damage = data.damage + 1
    end
    data.damage = data.damage + player:getMark(self.name)
  end,

  refresh_events = {fk.AfterCardsMove},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_refresh = function(self, event, target, player, data)
    for _, move in ipairs(data) do
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerEquip then
            if Fk:getCardById(info.cardId).sub_type == Card.SubtypeArmor then
              player.room:addPlayerMark(player, self.name, 1)
            end
          end
        end
      end
    end
  end,
}
sk__huchi:addRelatedSkill(sk__huchi_trigger)
godxuchu:addSkill(sk__huchi)
godxuchu:addSkill(sk__xiejia)
Fk:loadTranslationTable{
  ["sk__godxuchu"] = "神许褚",
  ["#sk__godxuchu"] = "嗜战的熊罴",

  ["sk__huchi"] = "虎痴",
  [":sk__huchi"] = "出牌阶段，你可以视为使用一张【决斗】（不能被【无懈可击】响应），以此法受到伤害的角色摸三张牌。若有角色因此伤害进入濒死状态"..
  "或此【决斗】没有造成伤害，此技能本阶段失效。",
  ["sk__xiejia"] = "卸甲",
  [":sk__xiejia"] = "锁定技，若你的装备区内没有防具牌，你使用【杀】和【决斗】对其他角色造成的伤害+1；当你失去装备区内的防具牌后，"..
  "本局游戏你使用【杀】和【决斗】对其他角色造成的伤害+1。",
  ["#sk__huchi"] = "虎痴：你可以视为使用【决斗】，受到伤害的角色摸三张牌！",
  ["@@sk__huchi-phase"] = "虎痴失效",

  ["$sk__huchi1"] = "哈哈哈哈哈！痛快，痛快！",
  ["$sk__huchi2"] = "不是你死，便是我亡！",
  ["$sk__xiejia1"] = "拔山扛鼎，力敌千钧！",
  ["$sk__xiejia2"] = "卸下重甲，方能战个痛快！",
  ["~sk__godxuchu"] = "居然……是我先倒下……",
}

local goddaqiao = General(extension, "sk__goddaqiao", "god", 3, 3, General.Female)
local sk__wangyued = fk.CreateTriggerSkill{
  name = "sk__wangyued",
  anim_type = "support",
  events = {fk.AfterCardsMove, fk.HpLost, fk.MaxHpChanged},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local room = player.room
      if event == fk.AfterCardsMove and player:getMark("sk__wangyued1-turn") == 0 then
        for _, move in ipairs(data) do
          if move.moveReason == fk.ReasonDiscard and move.from then
            self.cost_data = {1, move.from, #move.moveInfo}
            return table.find(room:getOtherPlayers(room:getPlayerById(move.from)), function(p)
              return not p.dead
            end)
          end
        end
      elseif event == fk.HpLost and player:getMark("sk__wangyued2-turn") == 0 then
        if table.find(room:getOtherPlayers(target), function(p)
          return p:isWounded()
        end) then
          self.cost_data = {2, target.id, data.num}
          return true
        end
      elseif event == fk.MaxHpChanged and player:getMark("sk__wangyued3-turn") == 0 then
        if data.num < 0 then
          self.cost_data = {3, target.id, -data.num}
          return table.find(room:getOtherPlayers(target), function(p)
            return not p.dead
          end)
        end
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local targets = room:getOtherPlayers(room:getPlayerById(self.cost_data[2]))
    if self.cost_data[1] == 2 then
      targets = table.filter(targets, function(p)
        return p:isWounded()
      end)
    end
    local to = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1,
      "#sk__wangyued"..self.cost_data[1].."-invoke:::"..self.cost_data[3], self.name, true)
    if #to > 0 then
      self.cost_data[2] = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "sk__wangyued"..self.cost_data[1].."-turn", 1)
    local to = room:getPlayerById(self.cost_data[2])
    if self.cost_data[1] == 1 then
      to:drawCards(self.cost_data[3], self.name)
    elseif self.cost_data[1] == 2 then
      room:recover({
        who = to,
        num = math.min(self.cost_data[3], to:getLostHp()),
        recoverBy = player,
        skillName = self.name,
      })
    elseif self.cost_data[1] == 3 then
      room:changeMaxHp(to, self.cost_data[3])
    end
  end,
}
local sk__luoyan = fk.CreateTriggerSkill{
  name = "sk__luoyan",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
      "#sk__luoyan-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAllPlayers()) do
      room:setPlayerMark(p, "@@sk__luoyan", 0)
    end
    room:setPlayerMark(room:getPlayerById(self.cost_data), "@@sk__luoyan", player.id)
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAllPlayers()) do
      room:setPlayerMark(p, "@@sk__luoyan", 0)
    end
  end,
}
local sk__luoyan_delay = fk.CreateTriggerSkill{
  name = "#sk__luoyan_delay",
  mute = true,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:getMark("@@sk__luoyan") ~= 0 and player.phase == Player.Play and not player.dead then
      local n = #player.room.logic:getEventsOfScope(GameEvent.UseCard, 4, function(e)
        local use = e.data[1]
        return use and use.from == player.id
      end, Player.HistoryPhase)
      if n < 4 then
        self.cost_data = n
        return true
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local src = room:getPlayerById(player:getMark("@@sk__luoyan"))
    src:broadcastSkillInvoke("sk__luoyan")
    room:notifySkillInvoked(src, "sk__luoyan", "control")
    room:doIndicate(src.id, {player.id})
    if self.cost_data == 1 then
      if not player:isNude() then
        local card = table.random(player:getCardIds("he"))
        room:throwCard(card, "sk__luoyan", player, player)
      end
    elseif self.cost_data == 2 then
      room:loseHp(player, 1, "sk__luoyan")
    elseif self.cost_data == 3 then
      room:changeMaxHp(player, -1)
    end
  end,
}
sk__luoyan:addRelatedSkill(sk__luoyan_delay)
goddaqiao:addSkill(sk__wangyued)
goddaqiao:addSkill(sk__luoyan)
Fk:loadTranslationTable{
  ["sk__goddaqiao"] = "神大乔",
  ["#sk__goddaqiao"] = "韶华易逝",

  ["sk__wangyued"] = "望月",
  [":sk__wangyued"] = "每回合各限一次：<br>1.当一名角色弃置牌后，你可以令另一名角色摸等量的牌；<br>2.当一名角色失去体力后，你可以令另一名角色"..
  "回复等量的体力；<br>3.当一名角色减少体力上限后，你可以令另一名角色增加等量的体力上限。",
  ["sk__luoyan"] = "落雁",
  [":sk__luoyan"] = "结束阶段，你可以选择一名角色，直到你再次发动此技能或你死亡，当其于其出牌阶段内：<br>使用第一张牌后，其随机弃置一张牌；<br>"..
  "使用第二张牌后，其失去1点体力；<br>使用第三张牌后，其减1点体力上限。",
  ["#sk__wangyued1-invoke"] = "望月：你可以令一名角色摸%arg张牌",
  ["#sk__wangyued2-invoke"] = "望月：你可以令一名角色回复%arg点体力",
  ["#sk__wangyued3-invoke"] = "望月：你可以令一名角色加%arg点体力上限",
  ["#sk__luoyan-choose"] = "落雁：你可以选择一名角色，其出牌阶段使用前三张牌后有负面效果！",
  ["@@sk__luoyan"] = "落雁",

  ["$sk__wangyued1"] = "清风吹寒裘，寒月照伊人。",
  ["$sk__wangyued2"] = "斜月照帘帷，念君何时归？",
  ["$sk__luoyan1"] = "秋风落黄叶，飘零独忆君。",
  ["$sk__luoyan2"] = "水影寒沾衣，独雁何处归？",
  ["~sk__goddaqiao"] = "伯符，我终于能再度与你相遇……",
}

local sp_godganning = General(extension, "sk_sp__godganning", "god", 4)
local sk__jieying = fk.CreateTriggerSkill{
  name = "sk__jieying",
  anim_type = "control",
  events = {fk.EventPhaseStart, fk.BeforeDrawCard, fk.PreHpRecover, fk.BeforeMaxHpChanged, fk.EventAcquireSkill},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target == player and player:hasSkill(self) and player.phase == Player.Draw and
          table.find(player.room:getOtherPlayers(player), function(p) return p:getMark("@sk__jieying") == 0 end)
      elseif target:getMark("@sk__jieying") > 0 and not target.dead then
        if event == fk.EventAcquireSkill then
          return data:isPlayerSkill(target) and data.visible
        else
          return data.num > 0
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local room = player.room
      local targets = table.map(table.filter(room:getOtherPlayers(player), function(p)
        return p:getMark("@sk__jieying") == 0 end), Util.IdMapper)
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#sk__jieying-invoke", self.name)
      if #to > 0 then
        self.cost_data = to[1]
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local to = room:getPlayerById(self.cost_data)
      room:addPlayerMark(to, "@sk__jieying", 3)
      return true
    else
      room:doIndicate(player.id, {target.id})
      room:removePlayerMark(target, "@sk__jieying", 1)
      if event == fk.BeforeDrawCard then
        player:drawCards(data.num, self.name)
        return true
      elseif event == fk.PreHpRecover then
        if player:isWounded() then
          room:recover({
            who = player,
            num = math.min(data.num, player:getLostHp()),
            recoverBy = player,
            skillName = self.name,
          })
        end
        return true
      elseif event == fk.BeforeMaxHpChanged then
        room:changeMaxHp(player, data.num)
        return true
      elseif event == fk.EventAcquireSkill then
        if not player:hasSkill(data.name, true) then
          room:handleAddLoseSkills(player, data.name, nil, true, false)
        end
        room:handleAddLoseSkills(target, "-"..data.name, nil, true, false)
      end
    end
  end,

  refresh_events = {fk.BeforeTurnStart},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(self) and target:getMark("@sk__jieying") > 0 and not target.dead and target:insideExtraTurn()
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    room:notifySkillInvoked(player, self.name)
    room:doIndicate(player.id, {target.id})
    room:removePlayerMark(target, "@sk__jieying", 1)

    room:sendLog{
      type = "#GainAnExtraTurn",
      from = player.id
    }
    room.current = player
    room.tag["_extra_turn_count"] = room.tag["_extra_turn_count"] or {}
    local ex_tag = room.tag["_extra_turn_count"]
    ex_tag[-1] = self.name

    room:sendLog{ type = "$AppendSeparator" }

    if not player.faceup then
      player:turnOver()
      return true
    end
    room.logic:trigger(fk.BeforeTurnStart, player)
  end,
}
local sk__jinlong = fk.CreateTriggerSkill{
  name = "sk__jinlong",
  anim_type = "special",
  frequency = Skill.Compulsory,
  derived_piles = "sk__jinlong",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local cards = {}
      for _, move in ipairs(data) do
        if (move.to == player.id and (move.toArea == Card.PlayerHand or move.toArea == Card.PlayerEquip)) or
          move.toArea == Card.DiscardPile then
          for _, info in ipairs(move.moveInfo) do
            if Fk:getCardById(info.cardId).type == Card.TypeEquip then
              table.insertIfNeed(cards, info.cardId)
            end
          end
        end
      end
      cards = U.moveCardsHoldingAreaCheck(player.room, cards)
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = self.cost_data
    player:addToPile(self.name, cards, true, self.name, player.id)
    if player.dead then return end
    player:drawCards(#cards, self.name)
    if player.dead then return end
    for _, id in ipairs(player:getPile(self.name)) do
      local card = Fk:getCardById(id)
      if card.equip_skill and not player:hasSkill(card.equip_skill) then
        room:handleAddLoseSkills(player, card.equip_skill.name, nil, false, true)
      end
    end
  end,

  refresh_events = {fk.AfterCardsMove},
  can_refresh = function (self, event, target, player, data)
    for _, move in ipairs(data) do
      if move.from and move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerSpecial and info.fromSpecialName == "sk__jinlong" then
            return true
          end
        end
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local skills = {}
    for _, skill in ipairs(player.player_skills) do
      if skill:isEquipmentSkill(player) then
        table.insert(skills, skill.name)
      end
    end
    if #player:getCardIds("e") > 0 then
      for _, id in ipairs(player:getCardIds("e")) do
        local card = Fk:getCardById(id)
        if card.equip_skill then
          table.removeOne(skills, card.equip_skill.name)
        end
      end
    end
    player.room:handleAddLoseSkills(player, "-"..table.concat(skills, "|-"), nil, false, true)
  end,
}
local sk__jinlong_attackrange = fk.CreateAttackRangeSkill{
  name = "#sk__jinlong_attackrange",
  correct_func = function (self, from, to)
    if #from:getPile("sk__jinlong") > 0 and from:hasSkill(sk__jinlong) then
      local nums = {}
      for _, id in ipairs(from:getPile("sk__jinlong")) do
        if Fk:getCardById(id).sub_type == Card.SubtypeWeapon then
          table.insert(nums, Fk:getCardById(id).attack_range)
        end
      end
      if #nums > 0 then
        return math.max(table.unpack(nums)) - 1
      end
    end
    return 0
  end,
}
sk__jinlong:addRelatedSkill(sk__jinlong_attackrange)
sp_godganning:addSkill(sk__jieying)
sp_godganning:addSkill(sk__jinlong)
Fk:loadTranslationTable{
  ["sk_sp__godganning"] = "神甘宁",
  ["#sk_sp__godganning"] = "锦翎如龙",

  ["sk__jieying"] = "劫营",
  [":sk__jieying"] = "摸牌阶段，你可以放弃摸牌，然后令一名未拥有“劫营”标记的其他角色获得3枚“劫营”标记。<br>拥有“劫营”标记的角色摸牌/"..
  "回复体力/增加体力上限/执行额外回合/获得技能前，你弃置其1枚“劫营”标记，改为由你执行对应的效果。",
  ["sk__jinlong"] = "锦龙",
  [":sk__jinlong"] = "锁定技，当装备牌进入你的手牌、装备区或弃牌堆后，将之置于你的武将牌上，然后你摸一张牌。你视为拥有这些装备牌的技能。",
  ["#sk__jieying-invoke"] = "劫营：你可以放弃摸牌，令一名角色获得3枚“劫营”标记",
  ["@sk__jieying"] = "劫营",

  ["$sk__jieying1"] = "劫寨将轻骑，驱兵饮巨瓯！",
  ["$sk__jieying2"] = "衔枚夜袭觇敌向，如若万鬼凌人间！",
  ["$sk__jinlong1"] = "身披锦衣卧沙场，银铃声声似龙吟！",
  ["$sk__jinlong2"] = "锦龙锐甲，金鳞为开！",
  ["~sk_sp__godganning"] = "神乌啼鸣尽悲哀，梧桐树下待涅槃！",
}

local godhuangzhong = General(extension, "sk__godhuangzhong", "god", 4)
local sk__liegong = fk.CreateViewAsSkill{
  name = "sk__liegong",
  anim_type = "offensive",
  pattern = "slash|.|.|.|fire__slash",
  prompt = "#sk__liegong",
  card_filter = function(self, to_select, selected)
    if Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand then
      if #selected == 0 then
        return true
      else
        return table.every(selected, function(id) return Fk:getCardById(to_select).suit ~= Fk:getCardById(id).suit end)
      end
    end
  end,
  view_as = function(self, cards)
    if #cards == 0 then return end
    local c = Fk:cloneCard("fire__slash")
    c.skillName = self.name
    c:addSubcards(cards)
    return c
  end,
  before_use = function(self, player, use)
    local n = #use.card.subcards
    if n >= 1 then
      use.unoffsetableList = table.map(player.room.alive_players, Util.IdMapper)
    end
    if n >= 3 then
      use.additionalDamage = (use.additionalDamage or 0) + 1
    end
  end,
  after_use = function(self, player, use)
    local n = #use.card.subcards
    if n >= 2 and not player.dead then
      player:drawCards(3, self.name)
    end
    if n >= 4 then
      local room = player.room
      for _, id in ipairs(TargetGroup:getRealTargets(use.tos)) do
        local to = room:getPlayerById(id)
        if use.damageDealt[id] and not to.dead then
          local skills = table.map(table.filter(to.player_skills, function(s)
            return s:isPlayerSkill(to) and s.visible
          end), function(s)
            return s.name
          end)
          if #skills > 0 then
            room:handleAddLoseSkills(to, "-"..table.random(skills), nil, true, false)
          end
        end
      end
    end
  end,
  enabled_at_play = function(self, player)
    return player:isWounded() and player:usedSkillTimes(self.name, Player.HistoryTurn) < 2 or
      player:usedSkillTimes(self.name, Player.HistoryTurn) < 1
  end,
  enabled_at_response = function(self, player, response)
    return not response and (player:isWounded() and player:usedSkillTimes(self.name, Player.HistoryTurn) < 2 or
      player:usedSkillTimes(self.name, Player.HistoryTurn) < 1)
  end,
}
local sk__liegong_targetmod = fk.CreateTargetModSkill{
  name = "#sk__liegong_targetmod",
  bypass_times = function(self, player, skill, scope, card, to)
    return table.contains(card.skillNames, "sk__liegong")
  end,
  bypass_distances =  function(self, player, skill, card, to)
    return table.contains(card.skillNames, "sk__liegong")
  end,
}
sk__liegong:addRelatedSkill(sk__liegong_targetmod)
godhuangzhong:addSkill(sk__liegong)
Fk:loadTranslationTable{
  ["sk__godhuangzhong"] = "神黄忠",
  ["#sk__godhuangzhong"] = "气概天参",

  ["sk__liegong"] = "烈弓",
  [":sk__liegong"] = "每回合限一次（若你已受伤，改为每回合限两次），你可以将任意张花色各不相同的手牌当无距离和次数限制的火【杀】使用，若以此法"..
  "使用的转化的牌数不少于：<br>1，此【杀】不能被【闪】响应；<br>2，使用此【杀】后，你摸三张牌；<br>3，此【杀】伤害+1；<br>"..
  "4，使用此【杀】后，若对目标角色造成伤害，令其随机失去一个技能。",
  ["#sk__liegong"] = "烈弓：将花色各不相同的手牌当火【杀】使用，根据牌数获得效果",
}

local sp_goddiaochan = General(extension, "sk_sp__goddiaochan", "god", 1, 1, General.Female)
local sk__lihun = fk.CreateTriggerSkill{
  name = "sk__lihun",
  anim_type = "control",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player), Util.IdMapper), 1, 1,
      "#sk__lihun-choose", self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    room:setPlayerMark(to, "@@sk__lihun", player.id)
    to:gainAnExtraTurn()
  end,

  refresh_events = {fk.BeforeTurnStart, fk.AfterTurnEnd},
  can_refresh = function(self, event, target, player, data)
    return target:getMark("@@sk__lihun") == player.id
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BeforeTurnStart then
      player:control(target)
      room:handleAddLoseSkills(target, "sk__lihun_active&", nil, false, true)
    else
      room:setPlayerMark(target, "@@sk__lihun", 0)
      room:handleAddLoseSkills(target, "-sk__lihun_active&", nil, false, true)
      target:control(target)
    end
  end,
}
local sk__lihun_active = fk.CreateActiveSkill{
  name = "sk__lihun_active&",
  mute = true,
  prompt = "#sk__lihun_active",
  card_filter =function (self, to_select, selected, player)
    local room = Fk:currentRoom()
    if #selected == 0 and room:getCardArea(to_select) ~= Card.PlayerEquip then
      local card = Fk:getCardById(to_select)
      return card.skill:canUse(player, card, {bypass_times = true, bypass_distances = true}) or
        table.contains({"peach", "ex_nihilo", "foresight", "bogus_flower", "wd_rice"}, card.trueName) or
        card.type == Card.TypeEquip or card.sub_type == Card.SubtypeDelayedTrick or card.multiple_targets  --预选目标救救
    end
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected_cards == 1 then
      local card = Fk:getCardById(selected_cards[1])
      if #selected >= card.skill:getMaxTargetNum(player, card) then return false end
      return true
    end
  end,
  feasible =function (self, selected, selected_cards, player)
    if #selected_cards == 1 then
      local card = Fk:getCardById(selected_cards[1])
      return #selected >= card.skill:getMinTargetNum() and #selected <= card.skill:getMaxTargetNum(player, card)
    end
  end,
  on_use = function(self, room, effect)
    room:useCard({
      from = effect.from,
      tos = table.map(effect.tos, function(pid) return { pid } end),
      card = Fk:getCardById(effect.cards[1]),
    })
  end,
}
local sk__lihun_targetmod = fk.CreateTargetModSkill{
  name = "#sk__lihun_targetmod",
  bypass_times = function(self, player, skill, scope, card)
    return card and scope == Player.HistoryPhase and player:getMark("@@sk__lihun") ~= 0
  end,
  bypass_distances = function (self, player, skill, card, to)
    return card and player:getMark("@@sk__lihun") ~= 0
  end,
}
local sk__jueshi = fk.CreateTriggerSkill{
  name = "sk__jueshi",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.BeforeMaxHpChanged, fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    if event == fk.BeforeMaxHpChanged then
      return true
    else
      local room = player.room
      while not player.dead and player.hp < 1 do
        local cards = table.filter(room.draw_pile, function(id)
          return Fk:getCardById(id).trueName == "peach" or Fk:getCardById(id).trueName == "analeptic"
        end)
        for _, p in ipairs(room:getAllPlayers()) do
          table.insertTable(cards, table.filter(p:getCardIds("h"), function(id)
            return Fk:getCardById(id).trueName == "peach" or Fk:getCardById(id).trueName == "analeptic"
          end))
        end
        if #cards == 0 then break end
        local card = Fk:getCardById(table.random(cards))
        if card.trueName == "peach" then
          room:useCard{
            from = player.id,
            tos = {{player.id}},
            card = card,
            extraUse = true,
          }
        elseif card.trueName == "analeptic" then
          room:useCard({
            from = target.id,
            tos = {{target.id}},
            card = card,
            extra_data = {analepticRecover = true},
            extraUse = true,
          })
        end
      end
    end
  end,

  refresh_events = {fk.GameStart, fk.EventAcquireSkill},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(self, true) and player.maxHp ~= 1
  end,
  on_refresh = function (self, event, target, player, data)
    player.maxHp = 1
    player.hp = math.min(player.hp, 1)
    player.room:broadcastProperty(player, "maxHp")
    player.room:broadcastProperty(player, "hp")
  end,
}
Fk:addSkill(sk__lihun_active)
sk__lihun:addRelatedSkill(sk__lihun_targetmod)
sp_goddiaochan:addSkill(sk__lihun)
sp_goddiaochan:addSkill(sk__jueshi)
Fk:loadTranslationTable{
  ["sk_sp__goddiaochan"] = "神貂蝉",
  ["#sk_sp__goddiaochan"] = "御世之傀儡师",

  ["sk__lihun"] = "离魂",
  [":sk__lihun"] = "回合结束时，你可以选择一名其他角色，该角色进行一个由你操控的额外回合，且于此额外回合内使用牌选择目标无需合法性检测。<br>"..
  "<font color = 'grey'><small>◆可以的操作例如：对自己使用杀，对其他角色使用装备，对指定的角色使用南蛮，对没有武器的角色借刀，对陆逊顺手牵羊，"..
  "对废除判定区的角色使用延时锦囊，对已有乐不思蜀的角色再贴乐；<br>"..
  "◆禁止的操作例如：虚空出闪（闪和无懈的目标是牌，没有目标不能虚空选择），对已死亡角色使用牌（？）；<br>"..
  "◆无法实现的操作例如：发动转化技指定不合法的目标，如武圣杀自己",
  ["sk__jueshi"] = "绝世",
  [":sk__jueshi"] = "锁定技，游戏开始时，将你的体力上限调整为1；你的体力上限改变时，防止之。当你进入濒死状态时，你随机使用所有角色手牌和"..
  "牌堆中的【桃】【酒】，直到全部使用完或脱离濒死状态。",
  ["#sk__lihun-choose"] = "离魂：你可以令一名其他角色进行一个额外回合，此回合由你操控为所欲为！",
  ["@@sk__lihun"] = "离魂",
  ["sk__lihun_active&"] = "离魂",
  [":sk__lihun_active&"] = "操控当前回合角色为所欲为！",
  ["#sk__lihun_active"] = "现在是离魂状态，使用牌选择目标无需合法性检测！",

  ["$sk__lihun1"] = "将军，你怎么魂不守舍的？",
  ["$sk__lihun2"] = "这点小事啊，不如，让妾身代劳吧~",
  ["$sk__jueshi1"] = "妾身，美吗？",
  ["$sk__jueshi2"] = "仙姿玉色，举世无双。",
  ["~sk_sp__goddiaochan"] = "还能……再见一次将军吗……",
}

local godxiaoqiao = General(extension, "sk__godxiaoqiao", "god", 3, 3, General.Female)
local function GetXingwu(player, src)
  if player.dead or src.dead then return end
  local room = player.room
  room:addPlayerMark(player, "@sk__xingwu", 1)
  if player:isWounded() then
    room:recover({
      who = player,
      num = 1,
      recoverBy = src,
      skillName = "sk__xingwu",
    })
  end
  if player.dead or src.dead then return end
  local skills = {}
  for _, general in ipairs(room.general_pile) do
    local g = Fk.generals[general]
    if player.gender ~= g.gender or g.gender == General.Bigender then
      table.insertTableIfNeed(skills, g:getSkillNameList())
    end
  end
  skills = table.filter(skills, function(s)
    return not player:hasSkill(s, true)
  end)
  if #skills == 0 then return end
  local skill = table.random(skills)
  local mark = player:getTableMark("sk__xingwu")
  table.insert(mark, skill)
  room:setPlayerMark(player, "sk__xingwu", mark)
  room:handleAddLoseSkills(player, skill, nil, true, false)
end
local function LoseXingwu(player, src)
  if player.dead or src.dead then return end
  local room = player.room
  room:removePlayerMark(player, "@sk__xingwu", 1)
  room:loseHp(player, 1, "sk__xingwu")
  if player.dead or src.dead then return end
  local skills = {}
  for _, g in pairs(Fk.generals) do
    if player.gender == g.gender or g.gender == General.Bigender then
      for _, s in ipairs(g:getSkillNameList()) do
        if player:hasSkill(s, true) then
          table.insertIfNeed(skills, s)
        end
      end
    end
  end
  if #skills == 0 then return end
  local skill = table.random(skills)
  local mark = player:getTableMark("sk__xingwu")
  table.removeOne(mark, skill)
  room:setPlayerMark(player, "sk__xingwu", mark)
  room:handleAddLoseSkills(player, "-"..skill, nil, true, false)
end
local sk__xingwu = fk.CreateTriggerSkill{
  name = "sk__xingwu",
  anim_type = "special",
  events = {fk.GameStart, fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return not player:isNude()
      end
    end
  end,
  on_trigger = function(self, event, target, player, data)
    if event == fk.GameStart then
      local n = player.hp
      self.cancel_cost = false
      for i = 1, n, 1 do
        if self.cancel_cost or not player:hasSkill(self) then break end
        self:doCost(event, target, player, n - i + 1)
      end
    else
      self:doCost(event, target, player, data)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      if room:askForSkillInvoke(player, self.name, nil, "#sk__xingwu-invoke:::"..data) then
        return true
      end
      self.cancel_cost = true
    else
      local targets = {}
      if target:getMark("@sk__xingwu") > 0 then
        targets = table.map(room:getOtherPlayers(target), Util.IdMapper)
      end
      local to, card =  room:askForChooseCardAndPlayers(player, targets, 0, 1, ".|.|heart",
        "#sk__xingwu-ask::"..target.id, self.name, true)
      if card then
        self.cost_data = {to, card}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      for _, p in ipairs(room:getAllPlayers()) do
        if player.dead then return end
        GetXingwu(p, player)
      end
    else
      room:throwCard(self.cost_data[2], self.name, player, player)
      if player.dead then return end
      if #self.cost_data[1] > 0 then
        local to = room:getPlayerById(self.cost_data[1][1])
        if not target.dead then
          LoseXingwu(target, player)
        end
        if player.dead then return end
        if not to.dead then
          GetXingwu(to, player)
        end
      elseif not target.dead then
        GetXingwu(target, player)
      end
      if player.dead or target.dead then return end
      local skills = target:getTableMark(self.name)
      if #skills > 0 and room:askForSkillInvoke(player, self.name, nil, "#sk__xingwu-switch::"..target.id) then
        local n = #skills
        local new_skills = {}
        for _, general in ipairs(room.general_pile) do
          local g = Fk.generals[general]
          if target.gender ~= g.gender or g.gender == General.Bigender then
            table.insertTableIfNeed(new_skills, g:getSkillNameList())
          end
        end
        new_skills = table.filter(new_skills, function(s)
          return not target:hasSkill(s, true) or not table.contains(skills, s)
        end)
        if #new_skills == 0 then return end
        new_skills = table.random(new_skills, n)
        room:setPlayerMark(target, "sk__xingwu", new_skills)
        room:handleAddLoseSkills(target, "-"..table.concat(skills, "|-").."|"..table.concat(new_skills, "|"), nil, true, false)
      end
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player and not table.find(player.room:getOtherPlayers(player), function(p)
      return p:hasSkill(self, true, true)
    end) then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(room:getAlivePlayers()) do
      local mark = p:getTableMark(self.name)
      if #mark > 0 then
        room:handleAddLoseSkills(p, "-"..table.concat(mark, "|-"), nil, true, false)
      end
      room:setPlayerMark(p, self.name, 0)
      room:setPlayerMark(p, "@sk__xingwu", 0)
    end
  end,
}
local sk__chenyu = fk.CreateTriggerSkill{
  name = "sk__chenyu",
  frequency = Skill.Compulsory,
  anim_type = "masochism",
  events = {fk.EventPhaseStart, fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and #player.room.alive_players > 1 then
      if event == fk.EventPhaseStart then
        return player.phase == Player.Finish
      else
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = {}
    for _, p in ipairs(room:getOtherPlayers(player)) do
      table.insertTable(cards, table.filter(p:getCardIds("h"), function(id)
        return Fk:getCardById(id).suit == Card.Heart
      end))
    end
    if #cards > 0 then
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
    end
  end,
}
godxiaoqiao:addSkill(sk__xingwu)
godxiaoqiao:addSkill(sk__chenyu)
Fk:loadTranslationTable{
  ["sk__godxiaoqiao"] = "神小乔",
  ["#sk__godxiaoqiao"] = "星河共舞",

  ["sk__xingwu"] = "星舞",
  [":sk__xingwu"] = "游戏开始时，你可以令所有角色各获得1枚“星舞”标记，你可以执行此流程至多X次（X为你的体力值）。<br>"..
  "一名角色回合开始时，你可以弃置一张<font color='red'>♥</font>牌，然后移动该角色的一枚“星舞”标记，或令其获得一枚“星舞”标记。若如此做，"..
  "你可以令其失去所有因“星舞”获得的技能并重新获得。<br>"..
  "当一名角色获得“星舞”标记后，你令其回复1点体力，然后其随机获得一个与其性别不同的武将的技能。<br>"..
  "当一名角色失去“星舞”标记后，你令其失去1点体力，然后其随机失去一个与其性别相同的武将的技能。",
  ["sk__chenyu"] = "沉鱼",
  [":sk__chenyu"] = "锁定技，结束阶段，或当你受到伤害后，你获得其他角色手牌中的<font color='red'>♥</font>牌。",
  ["#sk__xingwu-invoke"] = "星舞：是否令所有角色获得“星舞”标记？获得“星舞”标记同时会获得随机技能（还可以执行%arg次）",
  ["@sk__xingwu"] = "星舞",
  ["#sk__xingwu-ask"] = "星舞：你可以弃置一张<font color='red'>♥</font>牌，发动“星舞”<br>"..
  "若选择目标，则移动 %dest 的一枚“星舞”标记给该角色<br>若不选择目标，则令 %dest 获得一枚“星舞”标记",
  ["#sk__xingwu-switch"] = "星舞：是否将 %dest 的“星舞”技能替换成等量的随机技能？",
}

local sp_godhuangyueying = General(extension, "sk_sp__godhuangyueying", "god", 3, 3, General.Female)
local tiangong_info = {
  events = {
    "准备阶段开始时",
    "判定阶段开始时",
    "摸牌阶段开始时",
    "出牌阶段开始时",
    "出牌阶段结束时",
    "弃牌阶段开始时",
    "弃牌阶段结束时",
    "结束阶段开始时",
    "每回合限1~3次，当你的判定牌生效后",
    "每回合限1~3次，当你获得牌后",
    "每回合限1~3次，当你使用基本牌后",
    "每回合限1~3次，当你使用锦囊牌后",
    "每回合限1~3次，当你使用装备牌后",
    "每回合限1~3次，当你使用红色牌后",
    "每回合限1~3次，当你使用黑色牌后",
    "每回合限1~3次，当你成为普通锦囊牌的目标后",
    "每回合限1~3次，当你失去装备区内的牌后",
    "每回合限1~3次，当你成为【杀】的目标时",
    "每回合限1~3次，当你成为【杀】的目标后",
    "每回合限1~3次，当你使用或打出【杀】时",
    "每回合限1~3次，当你使用或打出【闪】时",
    "每回合限1~3次，当你造成伤害时",
    "每回合限1~3次，当你造成伤害后",
    "每回合限1~3次，当你受到伤害时",
    "每回合限1~3次，当你受到伤害后",
    "每回合限1~3次，当你回复体力或增加体力上限后",
    "每回合限1~3次，当你失去体力或减少体力上限后",
    "每回合限1~3次，当你进入濒死状态时",
    "每回合限1~3次，当你脱离濒死状态后",
    "每回合限1~3次，当你获得技能后",
    "每回合限1~3次，当你失去技能后",
    "每回合限1~3次，当你横置或重置或翻面后",
  },
  targets = {
    "你",
    "所有角色",
    "所有其他角色",
    "所有男性角色",
    "所有女性角色",
    "所有魏势力角色",
    "所有蜀势力角色",
    "所有吴势力角色",
    "所有群势力角色",
    "所有其他势力角色",
    "随机一名角色",
    "随机两名角色",
    "随机三名角色",
    "随机任意名角色",
    "体力上限最多的角色",
    "体力上限最少的角色",
    "体力值最多的角色",
    "体力值最少的角色",
    "手牌最多的角色",
    "手牌最少的角色",
    "随机一名未受伤角色",
    "随机两名未受伤角色",
    "所有未受伤角色",
    "随机一名已受伤角色",
    "随机两名已受伤角色",
    "所有已受伤角色",
  },
  effects = {
    "翻面",
    "进行一次【闪电】判定",
    "手牌上限+1",
    "出牌阶段使用【杀】次数上限+1",
    "随机失去一个技能",
    "随机获得一个魏势力武将技能",
    "随机获得一个蜀势力武将技能",
    "随机获得一个吴势力武将技能",
    "随机获得一个群势力武将技能",
    "随机获得一个其他势力武将技能",
    "视为使用【南蛮入侵】",
    "视为使用【万箭齐发】",
    "视为使用【桃园结义】",
    "视为使用【五谷丰登】",
    "视为使用【无中生有】",
    "视为使用【桃】",
    "视为对所有其他角色使用【杀】",
    "视为对所有其他角色使用雷【杀】",
    "视为对所有其他角色使用火【杀】",
    "视为对所有其他角色使用【决斗】",
    "从牌堆或弃牌堆随机获得两张红色牌",
    "从牌堆或弃牌堆随机获得两张黑色牌",
    "从牌堆或弃牌堆随机获得两张基本牌",
    "从牌堆或弃牌堆随机获得两张锦囊牌",
    "从牌堆或弃牌堆随机获得两张装备牌",
    "受到1点伤害",
    "受到1点雷电伤害",
    "受到1点火焰伤害",
    "对所有其他角色各造成1点伤害",
    "加1点体力上限",
    "减1点体力上限",
    "回复1点体力",
    "回复2点体力",
    "失去1点体力",
    "失去2点体力",
    "失去1点体力并摸五张牌",
    "摸两张牌",
    "摸三张牌",
    "摸四张牌",
    "随机弃置两张牌",
    "随机弃置三张牌",
    "随机弃置四张牌",
    "弃置所有牌并摸等量的牌",
    "随机获得所有其他角色各一张牌",
    "与随机一名手牌数更多的角色交换手牌",
    "与随机一名手牌数更少的角色交换手牌",
  }
}
local sk__tiangong_skills = {}
for loop = 1, 60, 1 do
  local m, n = loop%10, loop%12
  if m == 0 then
    m = 10
  end
  if n == 0 then
    n = 12
  end
  table.insert(sk__tiangong_skills, "sk__tiangong_create"..m..n)
  local sk__tiangong_create = fk.CreateTriggerSkill{
    name = "sk__tiangong_create"..m..n,
    anim_type = "special",
    frequency = Skill.Compulsory,
    events = {fk.EventPhaseStart, fk.EventPhaseEnd, fk.FinishJudge, fk.AfterCardsMove, fk.CardUseFinished, fk.TargetConfirmed,
      fk.TargetConfirming, fk.CardUsing, fk.CardResponding, fk.DamageCaused, fk.Damage, fk.DamageInflicted, fk.Damaged,
      fk.HpRecover, fk.MaxHpChanged, fk.HpLost, fk.EnterDying, fk.AfterDying, fk.EventAcquireSkill, fk.EventLoseSkill,
      fk.ChainStateChanged, fk.TurnedOver},
    can_trigger = function(self, event, target, player, data)
      if player:hasSkill(self) then
        if target then
          if target ~= player then return end
        end
        local info = player:getTableMark(self.name)[1]
        if info == 1 then
          return event == fk.EventPhaseStart and player.phase == Player.Start
        elseif info == 2 then
          return event == fk.EventPhaseStart and player.phase == Player.Judge
        elseif info == 3 then
          return event == fk.EventPhaseStart and player.phase == Player.Draw
        elseif info == 4 then
          return event == fk.EventPhaseStart and player.phase == Player.Play
        elseif info == 5 then
          return event == fk.EventPhaseEnd and player.phase == Player.Play
        elseif info == 6 then
          return event == fk.EventPhaseStart and player.phase == Player.Discard
        elseif info == 7 then
          return event == fk.EventPhaseEnd and player.phase == Player.Discard
        elseif info == 8 then
          return event == fk.EventPhaseStart and player.phase == Player.Finish
        else
          if player:usedSkillTimes(self.name, Player.HistoryTurn) >= (player:getTableMark(self.name)[4] or 0) then return end
          if info == 9 then
            return event == fk.FinishJudge
          elseif info == 10 then
            if event == fk.AfterCardsMove then
              for _, move in ipairs(data) do
                if move.to == player.id and move.toArea == Player.Hand then
                  return true
                end
              end
            end
          elseif info == 11 then
            return event == fk.CardUseFinished and data.card.type == Card.TypeBasic
          elseif info == 12 then
            return event == fk.CardUseFinished and data.card.type == Card.TypeTrick
          elseif info == 13 then
            return event == fk.CardUseFinished and data.card.type == Card.TypeEquip
          elseif info == 14 then
            return event == fk.CardUseFinished and data.card.color == Card.Red
          elseif info == 15 then
            return event == fk.CardUseFinished and data.card.color == Card.Black
          elseif info == 16 then
            return event == fk.TargetConfirmed and data.card:isCommonTrick()
          elseif info == 17 then
            if event == fk.AfterCardsMove then
              for _, move in ipairs(data) do
                if move.from == player.id then
                  for _, move_info in ipairs(move.moveInfo) do
                    if move_info.fromArea == Card.PlayerEquip then
                      return true
                    end
                  end
                end
              end
            end
          elseif info == 18 then
            return event == fk.TargetConfirming and data.card.trueName == "slash"
          elseif info == 19 then
            return event == fk.TargetConfirmed and data.card.trueName == "slash"
          elseif info == 20 then
            return (event == fk.CardUsing or event == fk.CardResponding) and data.card.trueName == "slash"
          elseif info == 21 then
            return (event == fk.CardUsing or event == fk.CardResponding) and data.card.trueName == "jink"
          elseif info == 22 then
            return event == fk.DamageCaused
          elseif info == 23 then
            return event == fk.Damage
          elseif info == 24 then
            return event == fk.DamageInflicted
          elseif info == 25 then
            return event == fk.Damaged
          elseif info == 26 then
            return event == fk.HpRecover or (event == fk.MaxHpChanged and data.num > 0)
          elseif info == 27 then
            return event == fk.HpLost or (event == fk.MaxHpChanged and data.num < 0)
          elseif info == 28 then
            return event == fk.EnterDying
          elseif info == 29 then
            return event == fk.AfterDying
          elseif info == 30 then
            return event == fk.EventAcquireSkill
          elseif info == 31 then
            return event == fk.EventLoseSkill and data:isPlayerSkill(player) and data.visible
          elseif info == 32 then
            return event == fk.ChainStateChanged or event == fk.TurnedOver
          end
        end
      end
    end,
    on_use = function(self, event, target, player, data)
      local room = player.room
      local targets = {}
      switch(player:getTableMark(self.name)[2], {
        [1] = function ()
          targets = {player}
        end,
        [2] = function ()
          targets = room:getAlivePlayers()
        end,
        [3] = function ()
          targets = room:getOtherPlayers(player)
        end,
        [4] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p.gender == General.Male or p.gender == General.Bigender
          end)
        end,
        [5] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p.gender == General.Female or p.gender == General.Bigender
          end)
        end,
        [6] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p.kingdom == "wei"
          end)
        end,
        [7] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p.kingdom == "shu"
          end)
        end,
        [8] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p.kingdom == "wu"
          end)
        end,
        [9] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p.kingdom == "qun"
          end)
        end,
        [10] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return not table.contains({"wei", "shu", "wu", "qun"}, p.kingdom)
          end)
        end,
        [11] = function ()
          targets = table.random(room:getAlivePlayers(), 1)
        end,
        [12] = function ()
          targets = table.random(room:getAlivePlayers(), 2)
        end,
        [13] = function ()
          targets = table.random(room:getAlivePlayers(), 3)
        end,
        [14] = function ()
          targets = table.random(room:getAlivePlayers(), math.random(#room.alive_players))
        end,
        [15] = function ()
          targets = table.filter(room:getAlivePlayers(), function(a)
            return table.every(room.alive_players, function(b)
              return a.maxHp >= b.maxHp
            end)
          end)
        end,
        [16] = function ()
          targets = table.filter(room:getAlivePlayers(), function(a)
            return table.every(room.alive_players, function(b)
              return a.maxHp <= b.maxHp
            end)
          end)
        end,
        [17] = function ()
          targets = table.filter(room:getAlivePlayers(), function(a)
            return table.every(room.alive_players, function(b)
              return a.hp >= b.hp
            end)
          end)
        end,
        [18] = function ()
          targets = table.filter(room:getAlivePlayers(), function(a)
            return table.every(room.alive_players, function(b)
              return a.hp <= b.hp
            end)
          end)
        end,
        [19] = function ()
          targets = table.filter(room:getAlivePlayers(), function(a)
            return table.every(room.alive_players, function(b)
              return a:getHandcardNum() >= b:getHandcardNum()
            end)
          end)
        end,
        [20] = function ()
          targets = table.filter(room:getAlivePlayers(), function(a)
            return table.every(room.alive_players, function(b)
              return a:getHandcardNum() <= b:getHandcardNum()
            end)
          end)
        end,
        [21] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return not p:isWounded()
          end)
          if #targets == 0 then return end
          targets = table.random(targets, 1)
        end,
        [22] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return not p:isWounded()
          end)
          if #targets == 0 then return end
          targets = table.random(targets, 2)
        end,
        [23] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return not p:isWounded()
          end)
        end,
        [24] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p:isWounded()
          end)
          if #targets == 0 then return end
          targets = table.random(targets, 1)
        end,
        [25] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p:isWounded()
          end)
          if #targets == 0 then return end
          targets = table.random(targets, 2)
        end,
        [26] = function ()
          targets = table.filter(room:getAlivePlayers(), function(p)
            return p:isWounded()
          end)
        end,
      })

      if #targets == 0 then return end
      room:doIndicate(player.id, table.map(targets, Util.IdMapper))

      local info = player:getTableMark(self.name)[3]
      for _, p in ipairs(targets) do
        if not p.dead then
          room:delay(500)
          SkUtil.DoTiangongEffect(player, p, info, self.name)
        end
      end
    end,
  }
  Fk:addSkill(sk__tiangong_create)
  local dic = {
    {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"},
    {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}
  }
  Fk:loadTranslationTable{
    ["sk__tiangong_create"..m..n] = dic[1][m]..dic[2][n],
    [":sk__tiangong_create"..m..n] = "锁定技，某时机，某些角色执行某些效果。（具体描述点击“机关技能”标记查看）",
  }
end
Fk:addQmlMark{
  name = "sk__tiangong_create",
  how_to_show = function(name, value)
    if type(value) == "table" then
      return tostring(#value)
    end
    return " "
  end,
  qml_path = "packages/jilvRem/qml/TiangongDetailBox"
}
local sk__tiangong = fk.CreateTriggerSkill{
  name = "sk__tiangong",
  anim_type = "special",
  events = {fk.GameStart, fk.TurnStart, fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and
      (not player.room.tag["sk__tiangong_skills"] or #player.room.tag["sk__tiangong_skills"] < 7) then
      if event == fk.GameStart then
        return true
      else
        return target == player
      end
    end
  end,
  on_trigger = function (self, event, target, player, data)
    self.cancel_cost = false
    if event == fk.GameStart then
      for i = 1, 2, 1 do
        if not player:hasSkill(self) or self.cancel_cost then return end
        self:doCost(event, target, player, data)
      end
    else
      self:doCost(event, target, player, data)
    end
  end,
  on_cost = function (self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name) then
      return true
    end
    self.cancel_cost = true
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room

    --初始化随机数
    math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 6)))

    --时机
    local nums = {}
    for i = 1, 32, 1 do
      table.insert(nums, i)
    end
    nums = table.random(nums, 3)
    local choices = {
      tiangong_info.events[nums[1]],
      tiangong_info.events[nums[2]],
      tiangong_info.events[nums[3]],
    }
    local choice_event = room:askForChoice(player, choices, self.name,
      "#sk__tiangong-choice_event")

    --目标
    nums = {}
    for i = 1, 26, 1 do
      table.insert(nums, i)
    end
    nums = table.random(nums, 3)
    choices = {
      tiangong_info.targets[nums[1]],
      tiangong_info.targets[nums[2]],
      tiangong_info.targets[nums[3]],
    }
    local choice_target = room:askForChoice(player, choices, self.name,
      "#sk__tiangong-choice_target:::"..choice_event)

    --效果
    nums = {}
    for i = 1, 46, 1 do
      table.insert(nums, i)
    end
    nums = table.random(nums, 3)
    choices = {
      tiangong_info.effects[nums[1]],
      tiangong_info.effects[nums[2]],
      tiangong_info.effects[nums[3]],
    }
    local choice_effect = room:askForChoice(player, choices, self.name,
      "#sk__tiangong-choice_effect:::"..choice_event..":"..choice_target)

    --选获得技能的角色
    local to = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
      "#sk__tiangong-choose:::"..choice_event..":"..choice_target..":"..choice_effect, self.name, false)
    to = room:getPlayerById(to[1])

    --获得技能名
    room.tag["sk__tiangong_skills"] = room.tag["sk__tiangong_skills"] or {}
    local name = table.random(sk__tiangong_skills)
    while table.contains(room.tag["sk__tiangong_skills"], name) do
      name = table.random(sk__tiangong_skills)
    end

    --房间记录技能信息
    table.insert(room.tag["sk__tiangong_skills"], name)
    local tiangong_scope = 999
    if table.indexOf(tiangong_info.events, choice_event) > 8 then
      tiangong_scope = math.random(3)
    end
    local mark = {
      table.indexOf(tiangong_info.events, choice_event),
      table.indexOf(tiangong_info.targets, choice_target),
      table.indexOf(tiangong_info.effects, choice_effect),
      tiangong_scope,
    }
    room.tag[name] = mark
    room:handleAddLoseSkills(to, name, nil, true, false)
  end,

  refresh_events = {fk.EventAcquireSkill, fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player then
      if event == fk.EventAcquireSkill or event == fk.EventLoseSkill then
        return table.contains(sk__tiangong_skills, data.name)
      elseif event == fk.Deathed then
        return table.find(player.player_skills, function (s)
          return table.contains(sk__tiangong_skills, s.name)
        end)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventAcquireSkill then
      room:setPlayerMark(player, data.name, room.tag[data.name])
      local show = player:getTableMark("@[sk__tiangong_create]")
      table.insert(show, {
        skillName = data.name,
        skillInfo = "锁定技，"..tiangong_info.events[room.tag[data.name][1]].."，"..
          tiangong_info.targets[room.tag[data.name][2]]..tiangong_info.effects[room.tag[data.name][3]].."。",
      })
      room:setPlayerMark(player, "@[sk__tiangong_create]", show)
    else
      local names = {}
      if event == fk.EventLoseSkill then
        names = {data.name}
      elseif event == fk.Deathed then
        for _, s in ipairs(player.player_skills) do
          if table.contains(sk__tiangong_skills, s.name) then
            table.insert(names, s.name)
          end
        end
      end
      for _, name in ipairs(names) do
        room:setPlayerMark(player, name, 0)
        local show = player:getTableMark("@[sk__tiangong_create]")
        for i = #show, 1, -1 do
          if show[i].skillName == name then
            table.remove(show, i)
          end
        end
        if #show == 0 then show = 0 end
        room:setPlayerMark(player, "@[sk__tiangong_create]", show)
        if not table.find(room:getOtherPlayers(player), function (p)
          return p:hasSkill(name, true)
        end) then
          table.removeOne(room.tag["sk__tiangong_skills"], name)
          room.tag[name] = {}
        end
      end
    end
  end,
}
local sk__linglong = fk.CreateTriggerSkill{
  name = "sk__linglong",
  anim_type = "defensive",
  events = {fk.DamageCaused, fk.PreHpLost, fk.BeforeMaxHpChanged, fk.EventLoseSkill},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      self.cost_data = {0}
      if event == fk.DamageCaused then
        if target and target ~= player and data.to == player then
          self.cost_data = {1}
        end
      elseif event == fk.PreHpLost then
        if target == player then
          self.cost_data = {2}
        end
      elseif event == fk.BeforeMaxHpChanged then
        if target == player and data.num < 0 then
          self.cost_data = {3}
        end
      elseif event == fk.EventLoseSkill then
        if target == player and data:isPlayerSkill(player) and data.visible then
          local e = player.room.logic:getCurrentEvent():findParent(GameEvent.SkillEffect)
          if e and e.data[3] == self then
            self.cost_data = {4}
          end
        end
      end
      if self.cost_data[1] ~= 0 then
        return table.find(player.player_skills, function(s)
          return s:isPlayerSkill(player) and s.visible and
            not table.contains(Fk.generals[player.general]:getSkillNameList(true), s.name) and
            (player.deputyGeneral == "" or not table.contains(Fk.generals[player.deputyGeneral]:getSkillNameList(true), s.name))
        end) or
        table.find(player.room:getOtherPlayers(player), function(p)
          return table.find(sk__tiangong_skills, function(s)
            return p:hasSkill(s, true)
          end)
        end)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local all_choices = {"sk__linglong1", "sk__linglong2", "Cancel"}
    local choices = {"Cancel"}
    if table.find(room:getOtherPlayers(player), function(p)
      return table.find(sk__tiangong_skills, function(s)
        return p:hasSkill(s, true)
      end)
    end) then
      table.insert(choices, 1, "sk__linglong2")
    end
    if table.find(player.player_skills, function(s)
      return s:isPlayerSkill(player) and s.visible and
        not table.contains(Fk.generals[player.general]:getSkillNameList(true), s.name) and
        (player.deputyGeneral == "" or not table.contains(Fk.generals[player.deputyGeneral]:getSkillNameList(true), s.name))
    end) then
      table.insert(choices, 1, "sk__linglong1")
    end
    local choice = room:askForChoice(player, choices, self.name, "#sk__linglong"..self.cost_data[1].."-invoke", false, all_choices)
    if choice ~= "Cancel" then
      self.cost_data = choice[13]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if self.cost_data == "1" then
      local skills = {}
      for _, s in ipairs(player.player_skills) do
        if s:isPlayerSkill(player) and s.visible and
          not table.contains(Fk.generals[player.general]:getSkillNameList(true), s.name) and
          (player.deputyGeneral == "" or not table.contains(Fk.generals[player.deputyGeneral]:getSkillNameList(true), s.name)) then
          table.insert(skills, s.name)
        end
      end
      local result = room:askForCustomDialog(player, self.name,
        "packages/utility/qml/ChooseSkillBox.qml", {
        skills, 1, 1, "#sk__linglong-choice"
      })
      local skill = ""
      if result == "" then
        skill = table.random(skills)
      end
      local choice = json.decode(result)
      if #choice > 0 then
        skill = choice[1]
      else
        skill = table.random(skills)
      end
      room:handleAddLoseSkills(player, "-"..skill, nil, true, false)
      if event == fk.EventLoseSkill then
        room:handleAddLoseSkills(player, data.name, nil, true, false)
        return
      else
        return true
      end
    else
      local tos = table.filter(room:getOtherPlayers(player), function(p)
        return table.find(sk__tiangong_skills, function(s)
          return p:hasSkill(s, true)
        end)
      end)
      local to = room:askForChoosePlayers(player, table.map(tos, Util.IdMapper), 1, 1, "#sk__linglong-choose", self.name, false)
      to = room:getPlayerById(to[1])
      local skills = {}
      for _, s in ipairs(to.player_skills) do
        if table.contains(sk__tiangong_skills, s.name) then
          table.insert(skills, s.name)
        end
      end
      if #skills == 1 then
        room:handleAddLoseSkills(to, "-"..skills[1], nil, true, false)
      elseif #skills > 1 then
        local result = room:askForCustomDialog(player, self.name,
          "packages/utility/qml/ChooseSkillBox.qml", {
          skills, 1, 1, "#sk__linglong-choice"
        })
        local skill = ""
        if result == "" then
          skill = table.random(skills)
        end
        local choice = json.decode(result)
        if #choice > 0 then
          skill = choice[1]
        else
          skill = table.random(skills)
        end
        room:handleAddLoseSkills(to, "-"..skill, nil, true, false)
      end
      if to.dead then return end
      if event == fk.DamageCaused then
        room:damage{
          from = data.from,
          to = to,
          damage = data.damage,
          damageType = data.damageType,
          skillName = data.skillName,
          chain = data.chain,
          card = data.card,
        }
        return true
      elseif event == fk.PreHpLost then
        room:loseHp(to, data.num, data.skillName)
        return true
      elseif event == fk.BeforeMaxHpChanged then
        room:changeMaxHp(to, data.num)
        return true
      elseif event == fk.EventLoseSkill then
        room:handleAddLoseSkills(player, data.name, nil, true, false)
        skills = table.map(table.filter(to.player_skills, function(s)
          return s:isPlayerSkill(p) and s.visible
        end), function(s)
          return s.name
        end)
        if #skills > 0 then
          room:handleAddLoseSkills(to, "-"..table.random(skills), nil, true, false)
        end
      end
    end
  end,
}
sp_godhuangyueying:addSkill(sk__tiangong)
sp_godhuangyueying:addSkill(sk__linglong)
Fk:loadTranslationTable{
  ["sk_sp__godhuangyueying"] = "神黄月英",
  ["#sk_sp__godhuangyueying"] = "巧绝天艺",

  ["sk__tiangong"] = "天工",
  [":sk__tiangong"] = "游戏开始时/回合开始时/回合结束时，你可以创造2/1/1个机关技能，并令一名角色获得之。所有角色至多拥有七个机关技能。<br>"..
  "<font color = 'grey'><small>◆机关技能：技能名为天干-地支组合，即六十甲子。由发动时机、目标、效果组合而成，均为锁定技。<br>"..
  "◆发动时机：准备阶段开始时；判定阶段开始时；摸牌阶段开始时；出牌阶段开始时；出牌阶段结束时；弃牌阶段开始时；弃牌阶段结束时；结束阶段开始时；"..
  "（以下时机均为每回合限X次，X为1~3）当你的判定牌生效后；当你获得牌后；当你使用基本牌后；当你使用锦囊牌后；当你使用装备牌后；"..
  "当你使用红色牌后；当你使用黑色牌后；当你成为普通锦囊牌的目标后；当你失去装备区内的牌后；当你成为【杀】的目标时；当你成为【杀】的目标后；"..
  "当你使用或打出【杀】时；当你使用或打出【闪】时；当你造成伤害时；当你造成伤害后；当你受到伤害时；当你受到伤害后；"..
  "当你回复体力或增加体力上限后；当你失去体力或减少体力上限后；当你进入濒死状态时；当你脱离濒死状态后；当你获得技能后；当你失去技能后；"..
  "当你横置或重置或翻面后。<br>"..
  "◆目标：你；所有角色；所有其他角色；所有男性角色；所有女性角色；所有魏势力角色；所有蜀势力角色；所有吴势力角色；所有群势力角色；"..
  "所有其他势力角色；随机一名角色；随机两名角色；随机三名角色；随机任意名角色；体力上限最多的角色；体力上限最少的角色；"..
  "体力值最多的角色；体力值最少的角色；手牌最多的角色；手牌最少的角色；随机一名未受伤角色；随机两名未受伤角色；所有未受伤角色；"..
  "随机一名已受伤角色；随机两名已受伤角色；所有已受伤角色。<br>"..
  "◆效果：翻面；进行一次【闪电】判定；手牌上限+1；出牌阶段使用【杀】次数上限+1；随机失去一个技能；随机获得一个魏势力武将技能；"..
  "随机获得一个蜀势力武将技能；随机获得一个吴势力武将技能；随机获得一个群势力武将技能；随机获得一个其他势力武将技能；"..
  "视为使用【南蛮入侵】；视为使用【万箭齐发】；视为使用【桃园结义】；视为使用【五谷丰登】；视为使用【无中生有】；视为使用【桃】；"..
  "视为对所有其他角色使用【杀】；视为对所有其他角色使用雷【杀】；视为对所有其他角色使用火【杀】；视为对所有其他角色使用【决斗】；"..
  "从牌堆或弃牌堆随机获得两张红色牌；从牌堆或弃牌堆随机获得两张黑色牌；"..
  "从牌堆或弃牌堆随机获得两张基本牌；从牌堆或弃牌堆随机获得两张锦囊牌；从牌堆或弃牌堆随机获得两张装备牌；"..
  "受到1点伤害；受到1点雷电伤害；受到1点火焰伤害；对所有其他角色各造成1点伤害；"..
  "加1点体力上限；减1点体力上限；回复1点体力；回复2点体力；失去1点体力；失去2点体力；失去1点体力并摸五张牌；"..
  "摸两张牌；摸三张牌；摸四张牌；随机弃置两张牌；随机弃置三张牌；随机弃置四张牌；弃置所有牌并摸等量的牌；"..
  "随机获得所有其他角色各一张牌；与随机一名手牌数更多的角色交换手牌；与随机一名手牌数更少的角色交换手牌。",
  ["sk__linglong"] = "玲珑",
  [":sk__linglong"] = "当其他角色对你造成伤害时/你失去体力时/你扣减体力上限前/你失去技能前，你可以选择一项：1.失去一个不为你武将牌上的技能，"..
  "防止此效果；2.令一名其他角色失去一个机关技能，然后将此效果转移给该角色。",
  ["#sk__tiangong-choice_event"] = "天工：选择技能的发动时机，当前技能为：<br>锁定技，",
  ["#sk__tiangong-choice_target"] = "天工：选择技能的目标，当前技能为：<br>锁定技，%arg，",
  ["#sk__tiangong-choice_effect"] = "天工：选择技能的效果，当前技能为：<br>锁定技，%arg，".."%arg2",
  ["#sk__tiangong-choose"] = "天工：将创造的技能交给一名角色：<br>锁定技，%arg，".."%arg2。",--FIXME:需要%arg3
  ["@[sk__tiangong_create]"] = "机关技能",
  ["#sk__linglong1-invoke"] = "玲珑：你即将受到伤害，是否发动“玲珑”防止或转移伤害？",
  ["#sk__linglong2-invoke"] = "玲珑：你即将失去体力，是否发动“玲珑”防止或转移失去体力？",
  ["#sk__linglong3-invoke"] = "玲珑：你即将减少体力上限，是否发动“玲珑”防止或转移减少体力上限？",
  ["#sk__linglong4-invoke"] = "玲珑：你即将失去技能，是否发动“玲珑”防止或转移失去技能？",
  ["sk__linglong1"] = "失去一个不为你武将牌上的技能，防止此效果",
  ["sk__linglong2"] = "令一名其他角色失去机关技能，效果转移给其",
  ["#sk__linglong-choice"] = "玲珑：选择失去的技能",
  ["#sk__linglong-choose"] = "玲珑：选择一名其他角色失去一个机关技能，并将效果转移给其",

  ["$sk__tiangong1"] = "巧艺天工，燃灯昼同。",
  ["$sk__tiangong2"] = "机关奇术，工巧若神。",
  ["$sk__linglong1"] = "新罗锦绣，七窍玲珑。",
  ["$sk__linglong2"] = "新眸流转，顾盼生姿。",
  ["$sk__tiangong_create1"] = "机关奇术，工巧若神。",
  ["$sk__tiangong_create2"] = "机巧之物，内有乾坤。",
  ["~sk_sp__godhuangyueying"] = "纵有慧心，乱世难安……",
}

local sk__godcaoren = General(extension, "sk__godcaoren", "god", 8)
local sk__bamen = fk.CreateTriggerSkill{
  name = "sk__bamen",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Play
  end,
  on_use = function(self, event, target, player, data)
    player:throwAllCards("h")
    if player.dead then return end

    local room = player.room
    local cardDic = {}
    for _, id in ipairs(room.draw_pile) do
      local name = Fk:getCardById(id).trueName
      cardDic[name] = cardDic[name] or {}
      table.insert(cardDic[name], id)
    end

    local toObtain = {}
    while #toObtain < 8 and next(cardDic) ~= nil do
      local dicLength = 0
      for _, ids in pairs(cardDic) do
        dicLength = dicLength + #ids
      end

      local randomIdx = math.random(1, dicLength)
      dicLength = 0
      for cardName, ids in pairs(cardDic) do
        dicLength = dicLength + #ids
        if dicLength >= randomIdx then
          table.insert(toObtain, ids[dicLength - randomIdx + 1])
          cardDic[cardName] = nil
          break
        end
      end
    end

    if #toObtain > 0 then
      room:moveCardTo(toObtain, Card.PlayerHand, player, fk.ReasonDraw, self.name, nil, false, player.id)
    end
    local n = 8 - #toObtain
    if n > 0 and not player.dead then
      local to = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player), Util.IdMapper), 1, 1,
        "#sk__bamen-damage:::"..n, self.name, true)
      if #to > 0 then
        room:damage{
          from = player,
          to = room:getPlayerById(to[1]),
          damage = n,
          damageType = fk.ThunderDamage,
          skillName = self.name,
        }
      end
    end
  end,
}
local sk__gucheng = fk.CreateTriggerSkill{
  name = "sk__gucheng",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target ~= player and data.to == player.id and
      (data.card.type == Card.TypeBasic or data.card:isCommonTrick()) and
      #player.room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local use = e.data[1]
        return use.from == player.id and use.card.trueName == data.card.trueName
      end, Player.HistoryGame) == 0
  end,
  on_use = function(self, event, target, player, data)
    table.insertIfNeed(data.nullifiedTargets, player.id)
  end,
}
sk__godcaoren:addSkill(sk__bamen)
sk__godcaoren:addSkill(sk__gucheng)
Fk:loadTranslationTable{
  ["sk__godcaoren"] = "神曹仁",
  ["#sk__godcaoren"] = "樊城天堑",

  ["sk__bamen"] = "八门",
  [":sk__bamen"] = "锁定技，出牌阶段开始时，你弃置所有手牌（无牌则不弃），然后摸八张牌名各不相同的牌，若你因牌堆牌名不足而少摸牌，"..
  "你可以对一名其他角色造成X点雷电伤害（X为以此法少摸的牌数）。",
  ["sk__gucheng"] = "孤城",
  [":sk__gucheng"] = "锁定技，其他角色使用基本牌或普通锦囊牌指定你为目标后，若你没有使用过此牌名的牌，此牌对你无效。",
  ["#sk__bamen-damage"] = "八门：你可以对一名角色造成%arg点雷电伤害！",

  ["$sk__bamen1"] = "整装列队，结八门金锁之阵。",
  ["$sk__bamen2"] = "哼，汝可识吾阵式？",
  ["$sk__gucheng1"] = "孤城临险，须坚壁清野。",
  ["$sk__gucheng2"] = "众将一心，严防死守！",
  ["~sk__godcaoren"] = "中计兵败，吾……愧对孟德……",
}

local sp_godsimayi = General(extension, "sk_sp__godsimayi", "god", 3)
local sk__yingshi = fk.CreateTriggerSkill{
  name = "sk__yingshi",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.AfterDrawInitialCards, fk.AfterCardsMove, fk.TurnEnd, fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.AfterDrawInitialCards then
        return target == player
      elseif event == fk.AfterCardsMove then
        local from, cards = 0, {}
        for _, move in ipairs(data) do
          if move.from and move.from ~= player.id and move.to == player.id and move.toArea == Player.Hand and
            not table.contains(player:getTableMark("sk__yingshi-turn"), move.from) then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand then
                from = move.from
                table.insert(cards, info.cardId)
              end
            end
          end
        end
        cards = U.moveCardsHoldingAreaCheck(player.room, cards)
        if #cards > 0 and table.every(cards, function(id)
          return Fk:getCardById(id).type == Card.TypeBasic
        end) and table.find(cards, function(id)
          return not table.contains(player:getTableMark(self.name), id)
        end) then
          self.cost_data = {from, cards}
          return true
        end
      elseif event == fk.TurnEnd then
        return table.find(player:getTableMark(self.name), function(id)
          return not table.contains(player:getCardIds("h"), id)
        end)
      elseif event == fk.CardUseFinished then
        return target == player and U.isPureCard(data.card) and table.contains(player:getTableMark(self.name), data.card.id)
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark(self.name)
    if event == fk.AfterDrawInitialCards then
      local choice = room:askForChoice(player, U.getAllCardNames("b", true), self.name, "#sk__yingshi-invoke")
      local cards = room:getCardsFromPileByRule(choice, 1, "drawPile")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
      end
      if player.dead then return end
      for _, id in ipairs(player:getCardIds("h")) do
        local card = Fk:getCardById(id)
        if card.type == Card.TypeBasic then
          table.insertIfNeed(mark, id)
          room:setPlayerMark(player, self.name, mark)
          room:setCardMark(card, "@@sk__yingshi", 1)
        end
      end
    elseif event == fk.AfterCardsMove then
      local record = player:getTableMark("sk__yingshi-turn")
      table.insert(record, self.cost_data[1])
      room:setPlayerMark(player, "sk__yingshi-turn", record)
      for _, id in ipairs(self.cost_data[2]) do
        table.insertIfNeed(mark, id)
        room:setPlayerMark(player, self.name, mark)
        room:setCardMark(Fk:getCardById(id), "@@sk__yingshi", 1)
      end
    elseif event == fk.TurnEnd then
      local cards = table.filter(player:getTableMark(self.name), function(id)
        return not table.contains(player:getCardIds("h"), id)
      end)
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, true, player.id)
      end
    elseif event == fk.CardUseFinished then
      player:drawCards(1, self.name)
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark(self.name)
    for _, id in ipairs(mark) do
      if not table.find(room:getOtherPlayers(player), function(p)
        return table.contains(p:getTableMark(self.name), id)
      end) then
        room:setCardMark(Fk:getCardById(id), "@@sk__yingshi", 0)
      end
    end
    room:setPlayerMark(player, self.name, 0)
  end,
}
local sk__yingshi_targetmod = fk.CreateTargetModSkill{
  name = "#sk__yingshi_targetmod",
  main_skill = sk__yingshi,
  bypass_times = function(self, player, skill, scope, card, to)
    return player:hasSkill(sk__yingshi) and player:usedSkillTimes("sk__yingshi", Player.HistoryGame) > 0 and
      card and card:getMark("@@sk__yingshi") > 0
  end,
  bypass_distances = function(self, player, skill, card, to)
    return player:hasSkill(sk__yingshi) and player:usedSkillTimes("sk__yingshi", Player.HistoryGame) > 0 and
      card and card:getMark("@@sk__yingshi") > 0
  end,
}
local sk__langxi = fk.CreateTriggerSkill{
  name = "sk__langxi",
  mute = true,
  events = {fk.GameStart, fk.CardUsing, fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif target == player and data.card:isCommonTrick() and U.IsUsingHandcard(player, data) then
        if event == fk.CardUsing then
          return not table.contains(player:getTableMark("@$sk__langxi"), data.card.trueName)
        else
          return data.tos and table.find(TargetGroup:getRealTargets(data.tos), function(id)
            return not player.room:getPlayerById(id).dead
          end) and #player:getTableMark("@$sk__langxi") > 0
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.GameStart then
      return true
    elseif event == fk.CardUsing then
      return player.room:askForSkillInvoke(player, self.name, nil, "#sk__langxi-record:::"..data.card.trueName)
    else
      local targets = TargetGroup:getRealTargets(data.tos)
      local tos = player.room:askForChoosePlayers(player, targets, 1, math.min(#targets, #player:getTableMark("@$sk__langxi")),
        "#sk__langxi-invoke", self.name)
      if #tos > 0 then
        self.cost_data = tos
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    local mark = player:getTableMark("@$sk__langxi")
    if event == fk.GameStart then
      local choices, all_names = {}, {}
      for _, id in ipairs(Fk:getAllCardIds()) do
        local card = Fk:getCardById(id)
        if card:isCommonTrick() and not card.is_derived then
          table.insertIfNeed(all_names, card.trueName)
          if not table.contains(mark, card.trueName) then
            table.insertIfNeed(choices, card.trueName)
          end
        end
      end
      if #choices == 0 then return end
      room:notifySkillInvoked(player, self.name, "special")
      local choice = room:askForChoice(player, choices, self.name, "#sk__langxi-choice", false, all_names)
      table.insert(mark, choice)
      room:setPlayerMark(player, "@$sk__langxi", mark)
    elseif event == fk.CardUsing then
      table.insert(mark, data.card.trueName)
      room:setPlayerMark(player, "@$sk__langxi", mark)
    elseif event == fk.CardUseFinished then
      room:notifySkillInvoked(player, self.name, "offensive")
      local targets = self.cost_data
      room:sortPlayersByAction(targets)
      local n = math.min(#targets, #mark)
      for i = 1, n, 1 do
        if player.dead then return end
        local to = room:getPlayerById(targets[i])
        if not to.dead then
          local card = Fk:cloneCard(mark[i])
          card.skillName = self.name
          local canUse = player:canUseTo(card, to, {bypass_distances = true, bypass_times = true}) and
            not (to ~= player and card.skill:getMinTargetNum() == 0 and not card.multiple_targets)
          local tos = {{to.id}}
          if canUse and card.skill:getMinTargetNum() == 2 then
            local seconds = {}
            Self = player
            for _, second in ipairs(room:getOtherPlayers(to)) do
              if card.skill:targetFilter(second.id, {to.id}, {}, card) then
                table.insert(seconds, second.id)
              end
            end
            if #seconds > 0 then
              local second = room:askForChoosePlayers(player, seconds, 1, 1,
                "#sk__langxi-second::"..to.id..":"..card:toLogString(), self.name, false, true)
              table.insert(tos, second)
            else
              canUse = false
            end
          end
          if canUse then
            local use = {
              from = player.id,
              tos = tos,
              card = card,
              extraUse = true,
            }
            room:useCard(use)
          end
        end
      end
    end
  end,

  refresh_events = {fk.EventLoseSkill, fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    if target == player then
      if event == fk.EventLoseSkill then
        return data == self
      else
        return player:hasSkill(self, true, true)
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "@$sk__langxi", 0)
  end,
}
local sk__shenyin = fk.CreateTriggerSkill{
  name = "sk__shenyin",
  anim_type = "special",
  frequency = Skill.Compulsory,
  events = {fk.GameStart, fk.Deathed, fk.TurnStart, fk.EnterDying, fk.EventLoseSkill},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif event == fk.Deathed then
        return data.damage and data.damage.from == player
      elseif player:getMark("@sk__shenyin") > 0 then
        if event == fk.TurnStart then
          return target == player and player:getMark("@sk__shenyin") > 0
        elseif event == fk.EnterDying then
          return target == player and player:getMark(self.name) ~= 0
        elseif event == fk.EventLoseSkill then
          return target == player and data == self and player:getMark(self.name) ~= 0
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      room:addPlayerMark(player, "@sk__shenyin", 1)
      local skills = table.map(table.filter(player.player_skills, function(s)
        return s:isPlayerSkill(player) and s.visible
      end), function(s)
        return s.name
      end)
      room:setPlayerMark(player, self.name, {player.hp, player.maxHp, skills,
        player:getTableMark("sk__yingshi"), player:getTableMark("@$sk__langxi")})
    elseif event == fk.Deathed then
      room:addPlayerMark(player, "@sk__shenyin", 1)
    elseif event == fk.TurnStart then
      local prompt = "#sk__shenyin-record1"
      if player:getMark(self.name) ~= 0 then
        prompt = "#sk__shenyin-record2:::"..player:getMark(self.name)[1]..":"..player:getMark(self.name)[2]
      end
      if room:askForSkillInvoke(player, self.name, nil, prompt) then
        local skills = table.map(table.filter(player.player_skills, function(s)
          return s:isPlayerSkill(player) and s.visible
        end), function(s)
          return s.name
        end)
        room:setPlayerMark(player, self.name, {player.hp, player.maxHp, skills,
          player:getTableMark("sk__yingshi"), player:getTableMark("@$sk__langxi")})
        room:addPlayerMark(player, "@sk__shenyin", 1)
      end
    elseif event == fk.EnterDying or event == fk.EventLoseSkill then
      local record = player:getMark(self.name)
      local prompt = "#sk__shenyin-load:::"..record[1]..":"..record[2]
      if room:askForSkillInvoke(player, self.name, nil, prompt) then
        player.maxHp = record[2]
        room:broadcastProperty(player, "maxHp")
        player.hp = record[1]
        room:broadcastProperty(player, "hp")

        local skills = {}
        for _, skill in ipairs(record[3]) do
          if not player:hasSkill(skill, true) then
            table.insert(skills, skill)
          end
        end
        for _, skill in ipairs(player.player_skills) do
          if skill:isPlayerSkill(player) and skill.visible and not table.contains(record[3], skill.name) then
            table.insert(skills, "-"..skill.name)
          end
        end
        room:handleAddLoseSkills(player, skills, nil, true, false)

        room:setPlayerMark(player, "sk__yingshi", record[4])
        local mark = player:getTableMark("sk__yingshi")
        if #mark > 0 then
          for _, id in ipairs(Fk:getAllCardIds()) do
            if table.find(room.alive_players, function(p)
              return table.contains(p:getTableMark(self.name), id)
            end) then
              room:setCardMark(Fk:getCardById(id), "@@sk__yingshi", 1)
            else
              room:setCardMark(Fk:getCardById(id), "@@sk__yingshi", 0)
            end
          end
        end
        room:setPlayerMark(player, "@$sk__langxi", record[5])

        if player.dead then return end
        player:drawCards(2 * player:getMark("@sk__shenyin"), self.name)
        room:setPlayerMark(player, "@sk__shenyin", 0)
      end
    end
  end,
}
sk__yingshi:addRelatedSkill(sk__yingshi_targetmod)
sp_godsimayi:addSkill(sk__yingshi)
sp_godsimayi:addSkill(sk__langxi)
sp_godsimayi:addSkill(sk__shenyin)
Fk:loadTranslationTable{
  ["sk_sp__godsimayi"] = "神司马懿",
  ["#sk_sp__godsimayi"] = "鹰挚狼食",

  ["sk__yingshi"] = "鹰视",
  [":sk__yingshi"] = "锁定技，分发起始手牌后，你选择一种基本牌牌名并从牌堆随机获得一张，然后将手牌中所有基本牌标记为“鹰”。<br>"..
  "每回合对每名角色限一次，当你获得其他角色的牌后，若这些牌均为基本牌，你将这些牌标记为“鹰”。<br>"..
  "一名角色的回合结束时，你从所有区域获得所有“鹰”。你使用“鹰”无距离和次数限制。当你使用“鹰”后，你摸一张牌。",
  ["sk__langxi"] = "狼袭",
  [":sk__langxi"] = "游戏开始时，你可以选择一张普通锦囊牌牌名标记为“狼”。当你使用普通锦囊牌手牌时，你可以将此牌名标记为“狼”。每种牌名限"..
  "记录一次。<br>当你使用普通锦囊牌手牌结算后，你可以视为对其中任意名目标角色依次使用“狼”。",
  ["sk__shenyin"] = "神隐",
  [":sk__shenyin"] = "锁定技，游戏开始时，你获得1枚“神隐”标记，并记录你当前的体力值、体力上限、拥有的技能和“鹰”“狼”标记。<br>"..
  "当你杀死其他角色后，你获得1枚“神隐”标记。<br>"..
  "回合开始时，若你有“神隐”标记，你可以记录你当前的体力值、体力上限、拥有的技能和“鹰”“狼”标记，然后获得1枚“神隐”标记。<br>"..
  "当你进入濒死状态时，或当你失去此技能后，你可以弃置所有“神隐”标记，恢复至记录的状态，并摸两倍弃置标记数的牌。",
  ["#sk__yingshi-invoke"] = "鹰视：获得一张你想要的基本牌",
  ["@@sk__yingshi"] = "鹰",
  ["@$sk__langxi"] = "狼",
  ["#sk__langxi-choice"] = "狼袭：选择一个牌名标记为“狼”",
  ["#sk__langxi-record"] = "狼袭：是否要将【%arg】标记为“狼”？",
  ["#sk__langxi-invoke"] = "狼袭：你可以视为对任意个目标依次使用“狼”",
  ["#sk__langxi-second"] = "狼袭：选择你对 %dest 使用%arg的副目标",
  ["@sk__shenyin"] = "神隐",
  ["#sk__shenyin-record1"] = "神隐：是否记录现在的状态？（当前没有记录）",
  ["#sk__shenyin-record2"] = "神隐：是否记录现在的状态？（之前的记录：体力值%arg，体力上限%arg2）",
  ["#sk__shenyin-load"] = "神隐：是否弃置神隐标记，恢复到记录的状态？（之前的记录：体力值%arg，体力上限%arg2）",

  ["$sk__yingshi1"] = "狡兔难逃，苍鹰之目！",
  ["$sk__yingshi2"] = "独占峰巅，展翅如风！",
  ["$sk__langxi1"] = "权变之袭，如狼噬骨！",
  ["$sk__langxi2"] = "腹生二心，自取罪戾！",
  ["$sk__shenyin1"] = "神幻幽妙，无以窥测。",
  ["$sk__shenyin2"] = "形藏于身，神隐于中。",
  ["~sk_sp__godsimayi"] = "天数已定，乱世终焉……",
}

local godcaopi = General(extension, "sk__godcaopi", "god", 3)
local sk__chuyuan = fk.CreateTriggerSkill{
  name = "sk__chuyuan",
  anim_type = "drawcard",
  derived_piles = "sk__godcaopi_chu",
  events = {fk.CardUseFinished, fk.DrawNCards},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:usedSkillTimes("sk__dengji", Player.HistoryGame) == 0 then
      if event == fk.CardUseFinished then
        return data.card.trueName == "slash" or data.card.trueName == "jink"
      else
        return target == player and table.find(player:getPile("sk__godcaopi_chu"), function(id)
          return Fk:getCardById(id).color == Card.Black
        end)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.CardUseFinished then
      return player.room:askForSkillInvoke(player, self.name)
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardUseFinished then
      player:drawCards(2, self.name)
      if player.dead or player:isNude() then return end
      local color, pattern = "black", ".|.|spade,club"
      if data.card.trueName == "jink" then
        color, pattern = "red", ".|.|heart,diamond"
      end
      if not table.find(player:getCardIds("he"), function(id)
        return Fk:getCardById(id):getColorString() == color
      end) then return end
      local card = room:askForCard(player, 1, 1, true, self.name, false, pattern, "#sk__chuyuan-card:::"..color)
      player:addToPile("sk__godcaopi_chu", card, true, self.name, player.id)
    else
      data.n = data.n + #table.filter(player:getPile("sk__godcaopi_chu"), function(id)
        return Fk:getCardById(id).color == Card.Black
      end)
    end
  end,
}
local sk__chuyuan_maxcards = fk.CreateMaxCardsSkill{
  name = "#sk__chuyuan_maxcards",
  main_skill = sk__chuyuan,
  correct_func = function(self, player)
    if player:hasSkill(sk__chuyuan) then
      return #table.filter(player:getPile("sk__godcaopi_chu"), function(id)
        return Fk:getCardById(id).color == Card.Red
      end)
    else
      return 0
    end
  end,
}
local sk__dengji = fk.CreateTriggerSkill{
  name = "sk__dengji",
  frequency = Skill.Wake,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      player.phase == Player.Start and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  can_wake = function(self, event, target, player, data)
    return #player:getPile("sk__godcaopi_chu") > 4 and
      #player:getPile("sk__godcaopi_chu") % 2 == 1
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = player:getPile("sk__godcaopi_chu")
    local red, black = #table.filter(cards, function(id)
      return Fk:getCardById(id).color == Card.Red
    end),
    #table.filter(cards, function(id)
      return Fk:getCardById(id).color == Card.Black
    end)
    room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, true, player.id)
    if player.dead then return end
    local skills = {}
    if black > red then
      table.insert(skills, "sk__jiquan")
    else
      table.insert(skills, "sk__renzheng")
    end
    local n = math.min(red, black)
    if n > 0 then
      local lord_skills = {}
      for _, g in ipairs(Fk:getAllGenerals()) do
        local skill = table.find(g.skills, function(s)
          return s.lordSkill
        end)
        if skill then
          table.insert(lord_skills, skill.name)
        end
      end
      table.insertTableIfNeed(skills, table.random(lord_skills, n))
    end
    room:handleAddLoseSkills(player, skills, nil, true, false)
  end,
}
local sk__jiquan = fk.CreateActiveSkill{
  name = "sk__jiquan",
  anim_type = "control",
  prompt = "#sk__jiquan",
  card_num = 0,
  min_target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter=function (self, to_select, selected, selected_cards, card, extra_data, player)
    if to_select ~= player.id then
      return not Fk:currentRoom():getPlayerById(to_select):isNude() or
        #Fk:currentRoom():getPlayerById(to_select).player_skills > 0
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:sortPlayersByAction(effect.tos)
    local targets = table.map(effect.tos, function(id)
      return room:getPlayerById(id)
    end)
    local mark = player:getTableMark(self.name)
    for _, id in ipairs(effect.tos) do
      mark[string.format("%.0f", id)] = (mark[string.format("%.0f", id)] or 0) + 1
    end
    room:setPlayerMark(player, self.name, mark)
    for _, target in ipairs(targets) do
      if player.dead then return end
      if not target.dead then
        local n = mark[string.format("%.0f", target.id)]
        room:setPlayerMark(target, "sk__jiquan-tmp", n)
        local success, dat = room:askForUseActiveSkill(target, "#sk__jiquan_active", "#sk__jiquan-choose:"..player.id.."::"..n, true)
        room:setPlayerMark(target, "sk__jiquan-tmp", 0)
        local skill, cards = "", {}
        if not success or (dat and
          ((dat.interaction == "Cancel" and #dat.cards == 0) or
          (dat.interaction ~= "Cancel" and player:hasSkill(dat.interaction, true)))) then
          local skills = table.map(table.filter(target.player_skills, function(s)
            return s:isPlayerSkill(target) and s.visible and not player:hasSkill(s, true)
          end), function(s)
            return s.name
          end)
          if #skills > 0 then
            skill = table.random(skills)
          else
            cards = table.random(target:getCardIds("he"), n)
          end
        elseif dat then
          if #dat.cards > 0 then
            cards = dat.cards
          else
            skill = dat.interaction
          end
        end
        if skill ~= "" then
          room:handleAddLoseSkills(player, skill, nil, true, false)
          room:handleAddLoseSkills(target, "-"..skill, nil, true, false)
        end
        if #cards > 0 then
          room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonGive, self.name, nil, false, target.id)
        end
      end
    end
    if player.dead then return end
    local n = 0
    for _, target in ipairs(targets) do
      n = n + target.maxHp
    end
    if player.maxHp <= n then
      room:changeMaxHp(player, 1)
      if not player.dead and player:isWounded() then
        room:recover({
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name
        })
      end
    end
  end,
}
local sk__jiquan_active = fk.CreateActiveSkill{
  name = "#sk__jiquan_active",
  mute = true,
  min_card_num = 0,
  target_num = 0,
  interaction = function(self,player)
    local skills = {"Cancel"}
    table.insertTable(skills, table.map(table.filter(player.player_skills, function(skill)
      return skill:isPlayerSkill(player) and skill.visible
    end), function(s)
      return s.name
    end))
    return UI.ComboBox {choices = skills}
  end,
  card_filter =function (self, to_select, selected, player)
    if self.interaction.data == "Cancel" then
      return #selected < player:getMark("sk__jiquan-tmp")
    else
      return false
    end
  end,
  feasible =function (self, selected, selected_cards, player)
    if #selected_cards > 0 then
      return self.interaction.data == "Cancel" and #selected_cards == player:getMark("sk__jiquan-tmp")
    else
      return true
    end
  end,
}
local sk__renzheng = fk.CreateActiveSkill{
  name = "sk__renzheng",
  anim_type = "support",
  prompt = function(self)
    return "#"..self.interaction.data
  end,
  min_card_num = function(self)
    if self.interaction.data == "sk__renzheng_card" then
      return 1
    else
      return 0
    end
  end,
  max_card_num = function(self)
    if self.interaction.data == "sk__renzheng_card" then
      return 999
    else
      return 0
    end
  end,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  interaction = function()
    return UI.ComboBox {choices = {"sk__renzheng_card", "sk__renzheng_skill"}}
  end,
  card_filter = function(self, to_select, selected)
    if self.interaction.data == "sk__renzheng_card" then
      return Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand
    else
      return false
    end
  end,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    if #selected == 0 and to_select ~= player.id then
      if self.interaction.data == "sk__renzheng_card" then
        return true
      else
        return true
      end
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    if self.interaction.data == "sk__renzheng_card" then
      room:moveCardTo(effect.cards, Player.Hand, target, fk.ReasonGive, self.name, nil, false, player.id)
    else
      local skills = table.map(table.filter(player.player_skills, function(skill)
        return skill:isPlayerSkill(player) and skill.visible and not target:hasSkill(skill, true)
      end), function(s)
        return s.name
      end)
      if #skills > 0 then
        local choices = room:askForChoices(player, skills, 1, #skills, self.name, "#sk__renzheng-choose::"..target.id, false)
        room:handleAddLoseSkills(target, choices, nil, true, false)
        room:handleAddLoseSkills(player, "-"..table.concat(choices, "|-"), nil, true, false)
      end
    end
    if player.dead then return end
    local mark = player:getTableMark(self.name)
    if not table.contains(mark, target.id) then
      table.insert(mark, target.id)
      room:setPlayerMark(player, self.name, mark)
      if room:askForSkillInvoke(player, self.name, nil, "#sk__renzheng-invoke::"..target.id) then
        room:changeMaxHp(player, 1)
        if not player.dead and player:isWounded() then
          room:recover({
            who = player,
            num = 1,
            recoverBy = player,
            skillName = self.name
          })
        end
        if target.dead then return end
        room:changeMaxHp(target, 1)
        if not target.dead and target:isWounded() then
          room:recover({
            who = target,
            num = 1,
            recoverBy = player,
            skillName = self.name
          })
        end
      end
    end
  end,
}
sk__chuyuan:addRelatedSkill(sk__chuyuan_maxcards)
Fk:addSkill(sk__jiquan_active)
godcaopi:addSkill(sk__chuyuan)
godcaopi:addSkill(sk__dengji)
godcaopi:addRelatedSkill(sk__jiquan)
godcaopi:addRelatedSkill(sk__renzheng)
Fk:loadTranslationTable{
  ["sk__godcaopi"] = "神曹丕",
  ["#sk__godcaopi"] = "代汉而立",

  ["sk__chuyuan"] = "储元",
  [":sk__chuyuan"] = "当一名角色使用【杀】/【闪】结算后，你可以摸两张牌，然后将一张黑色/红色牌置于你的武将牌上，称为“储”。<br>"..
  "每有一张黑色“储”，你摸牌阶段摸牌数+1；每有一张红色“储”，你手牌上限+1。",
  ["sk__dengji"] = "登极",
  [":sk__dengji"] = "觉醒技，准备阶段，若你的“储”数为奇数且不小于5，你获得所有“储”并令〖储元〗失效；若获得的黑色“储”多于红色“储”，"..
  "你获得〖极权〗，否则你获得〖仁政〗。每以此法获得一组黑色“储”和红色“储”，你随机获得一个主公技。",--原本是主公武将的技能（仁德奸雄etc，太无聊了）
  ["sk__jiquan"] = "极权",
  [":sk__jiquan"] = "出牌阶段限一次，你可以令任意名其他角色依次选择一项：1.交给你X张牌（X为你对其发动此技能的次数）；2.交给你一个技能。"..
  "然后若你的体力上限不大于目标角色的体力上限之和，你加1点体力上限并回复1点体力。",
  ["sk__renzheng"] = "仁政",
  [":sk__renzheng"] = "出牌阶段限一次，你可以将任意张手牌或技能交给一名其他角色，若是你第一次对其发动此技能，你可以令你与其"..
  "各加1点体力上限并回复1点体力。",
  ["#sk__chuyuan-card"] = "储元：请将一张%arg牌置为“储”",
  ["sk__godcaopi_chu"] = "储",
  ["#sk__jiquan"] = "极权：令任意名角色选择交给你牌或技能！",
  ["#sk__jiquan_active"] = "极权",
  ["#sk__jiquan-choose"] = "极权：交给 %src %arg张牌，或选择交给其的一个技能！（选“取消”随机失去一个技能）",
  ["#sk__renzheng_card"] = "仁政：将任意张手牌交给一名其他角色",
  ["#sk__renzheng_skill"] = "仁政：将任意个技能交给一名其他角色",
  ["sk__renzheng_card"] = "交出牌",
  ["sk__renzheng_skill"] = "交出技能",
  ["#sk__renzheng-choose"] = "仁政：选择要交给 %dest 的技能",
  ["#sk__renzheng-invoke"] = "仁政：是否与 %dest 各加1点体力上限并回复1点体力？",
}

local sp_godzhaoyun = General(extension, "sk_sp__godzhaoyun", "god", 1)
Fk:addQmlMark{
  name = "sk__qianyuan",
  how_to_show = function(name, value)
    if type(value) == "table" then
      return tostring(#value)
    end
    return " "
  end,
  qml_path = "packages/jilvRem/qml/ZhidiBox"
}
local QianyuanMapper = {
  [fk.DamageInflicted] = 1,
  [fk.PreHpLost] = 2,
  [fk.BeforeMaxHpChanged] = 3,
  [fk.BeforeCardsMove] = 4,
  [fk.EventLoseSkill] = 5,
  [fk.AfterSkillEffect] = 6,
  [fk.BeforeChainStateChange] = 7,
  [fk.BeforeTurnOver] = 8,
}
local function DoQianyuan(player, index, count, skill_name)
  local room = player.room
  if index == 1 then
    room:damage{
      to = player,
      damage = count,
      skillName = skill_name,
    }
  elseif index == 2 then
    room:loseHp(player, count, skill_name)
  elseif index == 3 then
    room:changeMaxHp(player, -count)
  elseif index == 4 then
    room:askForDiscard(player, count, count, true, skill_name, false)
  elseif index == 5 then
    local skills = table.map(table.filter(player.player_skills, function(s)
      return s:isPlayerSkill(player) and s.visible
    end), function(s)
      return s.name
    end)
    if #skills > 0 then
      room:handleAddLoseSkills(player, "-"..table.random(skills), nil, true, false)
    end
  elseif index == 6 then
    room:addPlayerMark(player, MarkEnum.SkInvalidity.."-turn", 1)
  elseif index == 7 then
    player:setChainState(true)
  elseif index == 8 then
    player:turnOver()
  end
end
local sk__qianyuan = fk.CreateTriggerSkill{
  name = "sk__qianyuan",
  anim_type = "defensive",
  events = {fk.DamageInflicted, fk.PreHpLost, fk.BeforeMaxHpChanged, fk.BeforeCardsMove, fk.EventLoseSkill,
    fk.AfterSkillEffect, fk.BeforeChainStateChange, fk.BeforeTurnOver},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self, true) then
      if event == fk.AfterSkillEffect then
        return (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan6") or
          player:getMark("sk__qianyuan-turn") < #player.room.alive_players) and
          table.find(player:getMarkNames(), function (name)
            return name:startsWith(MarkEnum.UncompulsoryInvalidity) or name:startsWith(MarkEnum.SkInvalidity)
          end)
      elseif player:hasSkill(self) then
        if event == fk.BeforeCardsMove then
          for _, move in ipairs(data) do
            if move.from == player.id and move.moveReason == fk.ReasonDiscard then
              if (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan4") or
                player:getMark("sk__qianyuan-turn") < #player.room.alive_players) then
                for _, info in ipairs(move.moveInfo) do
                  if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                    return true
                  end
                end
              end
            end
          end
        elseif target == player then
          if event == fk.BeforeMaxHpChanged then
            if data.num > 0 then return end
          elseif event == fk.EventLoseSkill then
            if not (data:isPlayerSkill(player) and data.visible) then return end
          elseif event == fk.BeforeChainStateChange then
            if player.chained then return end
          elseif event == fk.BeforeTurnOver then
            if not player.faceup then return end
          end
          return target == player and
            (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan"..QianyuanMapper[event]) or
            player:getMark("sk__qianyuan-turn") < #player.room.alive_players)
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan"..QianyuanMapper[event]) then
      return player.room:askForSkillInvoke(player, self.name, nil,
        "#sk__qianyuan2-invoke:::".."sk__qianyuan"..QianyuanMapper[event]..":"..player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, self.name, nil,
        "#sk__qianyuan1-invoke:::".."sk__qianyuan"..QianyuanMapper[event])
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan"..QianyuanMapper[event]) then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      if event == fk.BeforeCardsMove then
        local ids = {}
        for _, move in ipairs(data) do
          if move.from == player.id and move.moveReason == fk.ReasonDiscard then
            local new_info = {}
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                table.insertIfNeed(ids, info.cardId)
              else
                table.insert(new_info, info)
              end
              if #ids > 0 then
                move.moveInfo = new_info
              end
            end
          end
        end
        room:sendLog{
          type = "#cancelDismantle",
          card = ids,
          arg = self.name,
        }
      elseif event == fk.EventLoseSkill then
        room:handleAddLoseSkills(player, data.name, nil, false, false)
      elseif event == fk.AfterSkillEffect then
        for _, name in ipairs(player:getMarkNames()) do
          if name:startsWith(MarkEnum.UncompulsoryInvalidity) or name:startsWith(MarkEnum.SkInvalidity) then
            room:setPlayerMark(player, name, 0)
          end
        end
      end
      local nums = {1, 2, 3, 4, 5, 6, 7, 8}
      table.removeOne(nums, QianyuanMapper[event])
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog{
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan"..QianyuanMapper[event],
        arg2 = "sk__qianyuan"..rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record"..rand)
      end
      DoQianyuan(player, rand, count, self.name)
      if QianyuanMapper[event] < 4 or QianyuanMapper[event] > 6 then
        return true
      end
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan"..QianyuanMapper[event])
      if QianyuanMapper[event] < 4 or QianyuanMapper[event] > 6 then
        if event == fk.DamageInflicted then
          room:addPlayerMark(player, "sk__qianyuan_record1", data.damage)
        elseif event == fk.PreHpLost then
          room:addPlayerMark(player, "sk__qianyuan_record2", data.num)
        elseif event == fk.BeforeMaxHpChanged then
          room:addPlayerMark(player, "sk__qianyuan_record3", -data.num)
        end
        return true
      elseif event == fk.BeforeCardsMove then
        local ids = {}
        for _, move in ipairs(data) do
          if move.from == player.id and move.moveReason == fk.ReasonDiscard then
            local new_info = {}
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                table.insertIfNeed(ids, info.cardId)
              else
                table.insert(new_info, info)
              end
              if #ids > 0 then
                move.moveInfo = new_info
              end
            end
          end
        end
        room:addPlayerMark(player, "sk__qianyuan_record4", #ids)
        room:sendLog{
          type = "#cancelDismantle",
          card = ids,
          arg = self.name,
        }
      elseif event == fk.EventLoseSkill then
        room:handleAddLoseSkills(player, data.name, nil, false, false)
      elseif event == fk.AfterSkillEffect then
        for _, name in ipairs(player:getMarkNames()) do
          if name:startsWith(MarkEnum.UncompulsoryInvalidity) or name:startsWith(MarkEnum.SkInvalidity) then
            room:setPlayerMark(player, name, 0)
          end
        end
      end
    end
  end,
}
local sk__hualong = fk.CreateTriggerSkill{
  name = "sk__hualong",
  anim_type = "special",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Start and #player.room.alive_players > 1 and
      #player:getTableMark("@[sk__qianyuan]") > 0
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player), Util.IdMapper), 1, 1,
      "#sk__hualong-choose", self.name, true, true)
    if #to > 0 then
      self.cost_data = {tos = to}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local record = table.map(player:getTableMark("@[sk__qianyuan]"), function (str)
      return tonumber(str[13])
    end)
    room:addPlayerMark(player, self.name, #record)
    for _, i in ipairs(record) do
      if to.dead then break end
      if i == 4 and to:isNude() then
        --continue
      else
        local count = 1
        if i < 5 then
          count = player:getMark("sk__qianyuan_record"..i)
        end
        DoQianyuan(to, i, count, self.name)
      end
    end
    if player.dead then return end
    room:setPlayerMark(player, "@[sk__qianyuan]", 0)
    for i = 1, 4, 1 do
      room:setPlayerMark(player, "sk__qianyuan_record"..i, 0)
    end
    if player.maxHp <= player:getMark(self.name) then
      player.maxHp = player:getMark(self.name)
      player.hp = player:getMark(self.name)
      room:broadcastProperty(player, "maxHp")
      room:broadcastProperty(player, "hp")
    end
    if player:getHandcardNum() < player:getMark(self.name) then
      player:drawCards(player:getMark(self.name) - player:getHandcardNum(), self.name)
    end
  end,

  refresh_events = {fk.DrawNCards},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:getMark(self.name) > 0
  end,
  on_refresh = function (self, event, target, player, data)
    data.n = player:getMark(self.name)
  end,
}
local sk__hualong_targetmod = fk.CreateTargetModSkill{
  name = "#sk__hualong_targetmod",
  residue_func = function(self, player, skill, scope)
    if player:getMark("sk__hualong") > 0 then
      if skill.trueName == "slash_skill" and scope == Player.HistoryPhase then
        return player:getMark("sk__hualong") - 1
      elseif skill.trueName == "analeptic_skill" and scope == Player.HistoryTurn then
        return player:getMark("sk__hualong") - 1
      end
    end
  end,
}
local sk__hualong_attackrange = fk.CreateAttackRangeSkill{
  name = "#sk__hualong_attackrange",
  fixed_func = function (self, player)
    if player:getMark("sk__hualong") > 0 then
      return player:getMark("sk__hualong")
    end
  end,
}
local sk__hualong_delay = fk.CreateTriggerSkill{
  name = "#sk__hualong_delay",
  anim_type = "drawcard",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:getHandcardNum() < player:getMark("sk__hualong") then
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              return true
            end
          end
        end
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player:drawCards(player:getMark("sk__hualong") - player:getHandcardNum(), "sk__hualong")
  end,
}
sk__hualong:addRelatedSkill(sk__hualong_targetmod)
sk__hualong:addRelatedSkill(sk__hualong_attackrange)
sk__hualong:addRelatedSkill(sk__hualong_delay)
sp_godzhaoyun:addSkill(sk__qianyuan)
sp_godzhaoyun:addSkill(sk__hualong)
Fk:loadTranslationTable{
  ["sk_sp__godzhaoyun"] = "神赵云",
  ["#sk_sp__godzhaoyun"] = "破渊追天",

  ["sk__qianyuan"] = "潜渊",
  [":sk__qianyuan"] = "当你受到未记录的负面效果前，你可以令此效果对你无效，然后获得1枚“潜渊”标记并记录此负面效果。每回合限X次（X为存活角色数），"..
  "当你受到已记录的负面效果前，你可以将此负面效果改为随机另一种负面效果。<br>"..
  "<font color='grey'><small>负面效果：指受到伤害、失去体力、减体力上限、弃置牌、失去技能、技能失效、横置、翻面</small></font><br>"..
  "<font color='red'>注：此技能的“防止技能失效”时机可能有问题</font>",
  ["sk__hualong"] = "化龙",
  [":sk__hualong"] = "准备阶段，你可以选择一名其他角色并弃置所有“潜渊”标记，令其执行这些标记记录的负面效果，然后将你的体力上限、体力值、摸牌阶段"..
  "摸牌数、使用【杀】和【酒】次数上限、攻击范围和最小手牌数（失去手牌后，若手牌数小于X则摸至X张）调整为X（X为本局游戏弃置的“潜渊”标记总数）。",
  ["@[sk__qianyuan]"] = "潜渊",
  ["sk__qianyuan1"] = "受到伤害",
  ["sk__qianyuan2"] = "失去体力",
  ["sk__qianyuan3"] = "减体力上限",
  ["sk__qianyuan4"] = "弃置牌",
  ["sk__qianyuan5"] = "失去技能",
  ["sk__qianyuan6"] = "技能失效",
  ["sk__qianyuan7"] = "横置",
  ["sk__qianyuan8"] = "翻面",
  ["#sk__qianyuan1-invoke"] = "潜渊：你即将%arg，是否发动“潜渊”令此效果无效？",
  ["#sk__qianyuan2-invoke"] = "潜渊：你即将%arg，是否发动“潜渊”改为随机另一种负面效果？（本轮已用%arg2次）",
  ["#sk__qianyuanLog"] = "%from 将 %arg 改为 %arg2",
  ["#sk__hualong-choose"] = "化龙：你可以清空“潜渊”记录，令一名角色执行这些负面效果！",
  ["#sk__hualong_delay"] = "化龙",
}

return extension
